什么是类的继承?

继承是python 面向对象编程 的三大特性之一 

继承的好处,通过类的继承,可以使子类获取到父类的功能和属性

从程序语言上来说:继承就是 将公共的属性或者方法 封装到同一个类中,通过子类继承父类的方式,使子类具有了父类的属性和方法,提高了代码的可扩展性和重用行。

简单的来说:儿子没有钱,父亲有钱,儿子继承了父亲的钱,所以儿子也有钱花了,同时儿子还可以使用这笔钱 去赚更多的钱 比如开公司做生意等 。

 

继承父类的属性和方法 代码演示:

class animal():
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def run(self):
        print(self.name,'is running and age is %s'%self.age)

class dog(animal):
    pass

dog1 = dog('旺财',18)

# dog 是 animal的子类,自动继承animal的run 方法 和 属性
dog1.run()s



# 输出
#旺财 is running and age is 18

 

 子类特有的属性

# -*- coding: utf-8 -*-
'''
 Date: 2022/3/15 
 Author: byy
'''


class animal():

    def __init__(self,name,age):
        self.name = name
        self.age = age
    def info(self):
        print('狗子姓名:{},年龄:{}'.format(self.name,self.age))

class dog(animal):

    '''
    子类继承父类,除去父类的基本属性外,子类如有特有属性情况下,需使用super(),调用父类构造函数
    '''
    def __init__(self,name,age,weight=None):
        super().__init__(name,age)
        self.weight = weight

    def info(self):
        print('狗子姓名:{},年龄:{},体重:{}'.format(self.name,self.age,self.weight))

dog1 = dog('旺财',2,20)
dog1.info()



# 输出:

# 狗子姓名:旺财,年龄:2,体重:20

 

方法的继承:

# -*- coding: utf-8 -*-
'''
 Date: 2022/3/16 
 Author: byy
'''
class Super():

  def method1(self,a,b):
      print(a+b)


class Sub(Super):

  '''
  由于增加了参数,从而改变了同父类方法的一致性违反了LSP原则(在使用父类的场景,替换为子类也一样可行)。
  解决方式为,在子类重写的方法中为参数里添加默认值赋值,
  这样就确保了父类方法中定义的参数在子类中一定不会失效从而确保了自上而下的一致性
  '''
  # 子类方法重写了父类方法,并增加了参数c,将形参c设置一个默认值None 保证上下一致性
  def method1(self,a,b,c=None):
      super().method1(a,b)
      print(a+b+c)


s0 = Super()
s0.method1(2,2)

s = Sub()
s.method1(1,2,3)

#输出:
'''
4
3
6
'''

注意 签名一致性,如子类中 改变了父类方法参数并重写方法内容,

像这样 在 子类中直接添加参数,重写父类方法虽然也能正常使用,但是在pycharm里有警告提示:Signature of method 'Sub.method1()' does not match signature of the base method in class 'Super' 

由于增加了参数,从而改变了同父类方法的一致性违反了LSP原则(在使用父类的场景,替换为子类也一样可行)。解决方式为,在子类重写的方法中为参数里添加默认值赋值,这样就确保了父类方法中定义的参数在子类中一定不会失效从而确保了自上而下的一致性

 

 

学习中的问题:

在实例方法中self 标识的是实例对象本身,实例话对象后,通过实例调用实例方法 ,python 解释器会自动将实例作为参数传递给这个实例方法

即:我们实例化了一个对象之后,通过对象.方法(参数1,参数2)的方式调用实例方法的时候 ,实际python的调用 对象.方法(对象,参数1,参数2)

故以下例子中,如果对象调用传参个数大于 实际实例方法中的参数个数 将会报错类似:TypeError: method1() takes 4 positional arguments but 5 were given ,

子类的method1 方法需要self,a,b,c 这3个参数

实际对象 调用是传了 1,2,3,4+对象本身 ,即 传了 5个参数,故报错提示TypeError: method1() takes 4 positional arguments but 5 were given ,

# -*- coding: utf-8 -*-
'''
 Date: 2022/3/16 
 Author: byy
'''
class Super():

  def method1(self,a,b):
      print(a+b)


class Sub(Super):
  '''
  由于增加了参数,从而改变了同父类方法的一致性违反了LSP原则(在使用父类的场景,替换为子类也一样可行)。
  解决方式为,在子类重写的方法中为参数里添加默认值赋值,
  这样就确保了父类方法中定义的参数在子类中一定不会失效从而确保了自上而下的一致性
  '''
  # 子类方法重写了父类方法,并增加了参数c,将形参c设置一个默认值None 保证上下一致性
  def method1(self,a,b,c):
      print(a+b+c)


s0 = Super()
s0.method1(2,2)

s = Sub()
s.method1(1,2,3)

# 传入4个参数将报错,
# TypeError: method1() takes 4 positional arguments but 5 were given ,
# 因为在实例方法中 self 也是一个参数 ,在类外部调用实例方法传参,实际 python 解释器 在 执行时会把 实例本身作为参数 传递给 这个实例方法,故会有此提示
s.method1(1,2,3,4)