➢面向对象:【创建对象】–》【通过对象执行方法】
➢函数编程:【执行函数】
总结:
➢函数式的应用场景 --> 各个函数之间是独立且无共用的数据
➢面向对象编程的应用场景→各个函数公用一组数据
小练习:
写一个类,有四个方法,能够实现2个数字的加减乘除。
sum(self) sub(self) mul(self) div(self)
class ComputeTwoNumbers:
def __init__(self,a,b):
self.a = a
self.b = b
def sum(self):
return self.a+self.b
def sub(self):
return self.a-self.b
def mul(self):
return self.a*self.b
def div(self):
return self.a/self.b
c = ComputeTwoNumbers(4,2)
print(c.sum())
print(c.sub())
print(c.mul())
print(c.div())
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
➢普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
➢类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
➢静态方法:由类调用;无默认参数
小结几种方法的区别:
类方法可以被类对象或实例调用,实例方法只能被实例调用,它只属于类的单个实例拥有,静态方法两者都能调用,它在类和实例间共享。Python实现了一定的灵活性使得类方法和静态方法,都能够被实例和类二者调用。
所以三者主要区别在于参数传递上的区别,实例方法隐含传的参数是类实例self,而类方法隐含传递的参数是类本身cls,而静态方法无隐含参数,主要为了类实例也可以直接调用静态方法。
小练习:
写一个类,能够实现构造函数(有参数),
使用实例变量
实现实例方法
实现类方法
实现静态方法
写一下三个方法的调用程序
class Print:
def __init__(self,content):
self.content = content
def print_str(self):
print(self.content)
@classmethod
def print_file(cls,file_path):
with open(file_path) as fp:
print(fp.read())
print(dir(cls))
cls.print_file_line("f:\\a.txt",1)
@staticmethod
def print_file_line(file_path,line_number):
with open(file_path) as fp:
print(fp.readlines()[line_number-1])
p = Print("hi")
p.print_str()
p.print_file("f:\\a.txt")
p.print_file_line("f:\\a.txt",1)
继承的特点:
➢在继承中基类的构造(init()方法)不会被自动调用,它需要在其派生类的构造方法中专门调用,即子类不会继承基类的构造方法。
➢在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别于在类中调用普通函数时并不需要带上self参数。
➢Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找需要调用的方法,找不到才去基类中找)。
➢子类只继承父类所有公有的属性和方法,并且也可以在子类中通过父类名来调用,而对于私有的属性和方法,子类是不进行继承的,因此在子类中是无法通过父类名来访问的。
继承的本质
对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一实现每个方法。
小练习:
Bird 父类
name
sound
两个方法:打印名字和声音
子类:海鸥seagull
增加location属性
增加一个打印location的方法
把所有子类和父类的方法都调用一遍
class Bird(object):
def __init__(self,name,sound):
self.name = name
self.sound = sound
def get_name(self):
print(self.name)
def get_sound(self):
print(self.sound)
class seagull(Bird):
def __init__(self,name,sound,location):
Bird.__init__(self,name,sound)
self.location = location
def print_location(self):
print(self.location)
s = seagull("china seagull","yeye","china")
s.get_name()
s.get_sound()
s.print_location()
子类中的方法优先于父类中的方法举例(多用于方法的重写):
class Bird(object):
def __init__(self,name,sound):
self.name = name
self.sound = sound
def get_name(self):
print(self.name)
def get_sound(self):
print(self.sound)
class seagull(Bird):
def __init__(self,name,sound,location):
Bird.__init__(self,name,sound)
self.location = location
def print_location(self):
print(self.location)
def get_sound(self): #重写
print("gaga!")
s = seagull("china seagull","yeye","china")
s.get_name()
s.get_sound()
s.print_location()
两种调用父类的方法:
1、Parent.parentMethod(self)
2、self.parentMethod()
第一种是直接用父类的类名.方法名去调用父类的方法,但是需要注意的是,这种调用方法必须将self作为参数传进去并且作为第一个参数,表示指向这个类的实例本身。这种方法多用于方法重写时。
第二种是直接用self去调用父类的方法,为什么可以这样调用呢?因为一旦子类继承了父类,那么子类就拥有父类所有的公有方法和属性,所以此时父类的方法和属性就相当于子类自己了,所以可以直接用self去直接调用实例的方法,而不用再传入self参数了。
class Bird(object):
def __init__(self,name,sound):
self.name = name
self.sound = sound
def get_name(self):
print(self.name)
def get_sound(self):
print(self.sound)
class seagull(Bird):
def __init__(self,name,sound,location):
Bird.__init__(self,name,sound)
self.location = location
def print_location(self):
print(self.location)
Bird.get_name(self)
Bird.get_sound(self)
s = seagull("china seagull","yeye","china")
s.print_location()
class Bird(object):
def __init__(self,name,sound):
self.name = name
self.sound = sound
def get_name(self):
print(self.name)
def get_sound(self):
print(self.sound)
class seagull(Bird):
def __init__(self,name,sound,location):
Bird.__init__(self,name,sound)
self.location = location
def print_location(self):
print(self.location)
self.get_name()
self.get_sound()
s = seagull("china seagull","yeye","china")
s.print_location()
调用父类的__init__方法
我们知道,子类继承基类后,在子类定义了自己的构造方法后,基类的构造方法不会被主动继承,所以基类构造函数中初始化的一些属性在子类中是不具有的,但是我们又想用这些属性,怎么办?
这个时候有两种方法,一是在子类构造方法中再写一次这些属性,二是直接调用父类的构造方法完成。当然我们一般采用第二种发法。
子类调用基类的构造函数有两种方法,基本语法如下:
1、super(subclassName, self).init( [parameter1[,parameter2…]])
2、superclassName.init(self, [parameter1[,parameter2…]])
注意:
两次参数列表中的self参数都是必不可少的,如果基类的构造方法中有除了self参数外别的参数,调用时,也必须传入同等数量、同等类型的参数。
当子类不定义自己的构造方法时,默认会自动调用父类的构造方法。
Python中super函数只能在构造方法中使用。
class Bird(object):
def __init__(self,name,sound):
self.name = name
self.sound = sound
def get_name(self):
print(self.name)
def get_sound(self):
print(self.sound)
class seagull(Bird):
def __init__(self,name,sound,location):
super(seagull,self).__init__(name,sound)
self.location = location
def print_location(self):
print(self.location)
Bird.get_name(self)
Bird.get_sound(self)
s = seagull("china seagull","yeye","china")
s.print_location()