类的继承和多态学习笔记
类的继承:
面向对象(OOP)的一大特色就是: 继承;继承拥有这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程,继承的最大好处就是:子类获得了父类的全部功能
继承概念的实现方式主要有2类:实现继承、接口继承。
- 实现继承是指使用基类的属性和方法而无需额外编码的能力。
- 接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法)。
在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。
继承类的构造方法:
1.经典类的写法: 父类名称.__init__(self,参数1,参数2,...)
2. 新式类的写法:super(子类,self).__init__(参数1,参数2,....)
class Person(object): # 定义一个父类
def __init__(self,name,gender,age,heigh,weight,country='China'):
self.name = name
self.gender = gender
self.age = age
self.heigh = heigh
self.weight = weight
self.country = country
def get_func(self): # 父类中的方法
return self.name,self.gender,self.age,self.heigh,self.weight,self.country
class Student(Person): # 定义一个子类, 继承Person类
def __init__(self,name,gender,age,heigh,weight,score,language):
# 也可以写成: super(Student,self).__init__(name,gender,age,heigh,weight)
Person.__init__(self,name,gender,age,heigh,weight)
self.score = score # 定义子类的本身属性
self.language = language
def get_info(self): # 在子类中定义其自身的方法
return self.score,self.language
student1 = Student('Gavin','gentleman',26,178,'65kg',100,'English')
print(student1)
print('---------可爱的分割线---------')
print(student1.get_info()) # student1.get_info() 调用本身的方法
print('---------我才是可爱的分割线---------')
print(student1.get_func()) # student1.get_func() 调用继承的Person类的方法
print('---------我才是最可爱的分割线---------')
L = list(student1.get_func()) #将调用子类的方法得到的结果追加到 调用父类得到的结果后面
for i in list(student1.get_info()):
L.append(i)
print(L)
print('---------那我呢。。。。。---------')
print(student1.country) # 子类调用 父类中的属性
print(student1.name)
如果我们只是简单的在子类Student中定义一个构造函数,其实就是在重构。这样子类就不能继承父类的属性了。所以我们在定义子类的构造函数时,要先继承、再构造,这样我们也能获取父类的属性了。
子类构造函数基于父类构造函数过程如下:
实例化对象student1 ----> student1 调用子类__init__() ---- > 子类__init__()继承父类__init__() ----- > 调用父类 __init__()
当子类调用父类中的属性和方法的时候,会沿着继承树向上查找,找到了,就可以成功调用了
继承可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写
多态:
class Animal(object):
def run(self):
return 'Animal is running....'
class Dog(Animal):
pass
class Cat(Animal):
pass
D = Dog()
C = Cat()
print(D.run())
print('-----------------------')
print(C.run())
class Animal(object):
def run(self):
return 'Animal is running....'
class Dog(Animal):
def run(self):
return 'Dog is running....'
class Cat(Animal):
def run(self):
return "Cat is running"
D = Dog()
C = Cat()
print(D.run())
print('-----------------------')
print(C.run())
对比这两段代码的运行结果可以发现:当子类中没有 run() 函数是,会继承父类中的run() 函数;当子类和父类中都存在相同的run函数时,代码运行时总会先调用 子类中的 run 函数,我们可以认为 子类的 run() 函数覆盖了 父类的run() 函数,这样就获得了继承的另一个好处: 多态
多态性使用的前提:①类的继承关系 ②要有方法重写。python中的多态体现
python这里的多态性是指具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容的函数。
class Father(object):
def __init__(self,money):
self.money = money
def p(self):
return 'This is father!'
class Son(Father):
def __init__(self,money,job):
super(Son,self).__init__(money)
self.job = job
def p(self):
return 'This is son,我重写了父类方法!'
class Daughter(Father):
def __init__(self,money,job):
Father.__init__(self,money)
self.job = job
def p(self):
return 'This is daughter,我重写了父类方法!','10亿'
# 定义一个函数,函数调用类中的 p() 方法
def fc(var):
return var.p()
son = Son('150万','CEO')
daughter = Daughter('100万','artist')
# 这里的多态性体现是向同一个函数,传递不同的参数后,可以实现不同的功能
print(fc(son))
print('----------------------------')
print(fc(daughter))
Son 和 Daughter 两个类可以不加修改的使用 fc() 函数,原因就在于 : 多态
多态, 不同的 子类对象调用 相同的 父类方法,产生 不同的 执行结果,可以增加代码的外部 调用灵活度,
- 多态以 继承 和 重写 父类方法 为前提
- 多态是调用方法的技巧,不会影响到类的内部设计
Reference: