类的继承和多态学习笔记

类的继承:

面向对象(OOP)的一大特色就是: 继承;继承拥有这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程,继承的最大好处就是:子类获得了父类的全部功能

继承概念的实现方式主要有2类:实现继承、接口继承。

  1. 实现继承是指使用基类的属性和方法而无需额外编码的能力。
  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:

python类的继承