面向对象-类的继承
类的继承
1、概述
面向对象编程最大的好处就是实现了代码的重用 代码的重用是通过继承来去实现的 继承就分为父类和子类 被继承的类称为父类、超类、基类,继承后新的类称为子类
2、单一继承
-
格式
class 父类: pass class 子类(父类): pass
-
好处
继承最大的好处(代码的重用) 子类什么事都没做 就拥有了父类的所有属性和方法
-
注意
私有不能被继承
-
实例
所有公有属性和方法的继承
class A(object): money = 1000 def say(self): print('我老有钱了', self.money) # 子类B什么都没做 就拥有了父类的所有公有属性和方法 class B(A): pass a = A() print(a.money) a.say() b = B() print(b.money) b.say()
私有属性和方法的继承(私有都不能被继承(私有属性/私有方法))
class A: name = 'A' __age = 18 def say(self): print('我叫:{} 我今年{}岁了'.format(self.name, self.__age)) # 公有方法调用私有方法 self.__private_method() def __private_method(self): print('我就是一个私有方法') class B(A): def test_private(self): # print(self.__age) self.__private_method() a = A() print(a.name) a.say() b = B() print(b.name) b.say() b = B() b.test_private() # 私有都不能被继承(私有属性/私有方法)
父类方法的重写(不影响父类)
class A: name = '' def __init__(self, name): self.name = name def say(self): # self依然是谁调用就是谁 print('A', self.__class__) print('我叫:',self.name) class B(A): # 对于父类方法的重写啊(覆盖掉了) def say(self): print('我是子类的say', self.name) a = A('张三') a.say() b = B('张三') b.say()
完整实例
class People: # 定义基本属性 name = '' age = 0 # 定义私有属性 __weight = 0 # 定义构造方法 def __init__(self, n, a, w): self.name = n self.age = a self.__weight = w def speak(self): print("{} 说我今年{}岁了 ".format(self.name, self.age)) # p = People('lucky', 18, 99) # p.speak() class Stu(People): # 基本属性 grade = '' def __init__(self, n, a, w, g): People.__init__(self, n, a, w) self.grade = g def speak(self): print('{}说 我今年{}岁了 我在读{}'.format(self.name, self.age, self.grade)) # s = Stu('lucky', 18, 99) s = Stu('lucky', 18, 99, '小学五年级') s.speak()
3、多继承
-
格式
class 子类(父类1[,父类2...]): pass
-
注意
需要注意继承父类的顺序 若是基类中有相同的方法名的时候 而在子类中未指定 会在父类中按照从左至右的顺序进行搜索 即在子类中不存在该方法 则去父类从左至右进行查找 直至查到为止
-
实例
class A: def a(self): print('A类中的a方法') class B: val = '值' def b(self): print('B类中的b方法', self.val) class C(A, B): pass c = C() # print(c.val) # c.a() c.b()
将之前的people、stu变成多继承
class People: # 定义基本属性 name = '' age = 0 # 定义私有属性 __weight = 0 # 定义构造方法 def __init__(self, n, a, w): self.name = n self.age = a self.__weight = w def speak(self): print("{} 说我今年{}岁了 ".format(self.name, self.age)) class Stu(People): # 基本属性 grade = '' def __init__(self, n, a, w, g): People.__init__(self, n, a, w) self.grade = g def speak(self): print('{}说 我今年{}岁了 我在读{}'.format(self.name, self.age, self.grade)) class Speaker: # 给speaker类定义基本属性 topic = '' name = '' def __init__(self, n, t): self.topic = t self.name = n def speak(self): print('我叫:{} 我是一个演说家 我演讲的话题是:{}'.format(self.name, self.topic)) # 多重继承 class Sample(Speaker, Stu): val = '' # 定义sample基本属性 def __init__(self, n, a, w, g, t, val): Speaker.__init__(self, n, t) Stu.__init__(self, n, a, w, g) self.val = val # s = Sample('lucky', '学习python') # s = Sample('lucky', 18, 99, 'python36') s = Sample('lucky', 18, 99, 'python36', '学习python', 'default') s.speak()
4、调用父类方法
-
方式
-
方式一
super(类名, self).method()
-
方式二(建议)
super().method()
-
方式三
类名.method(self)
-
-
注意
- 如果是单继承 则super自动调用父类被覆盖的方法
- 如果是多继承 super会从最左侧的类开始查找 遇到则调用
- 使用super(类名, self) 调用方式 会根据你给的类名 往右开始进行查找 查找成功则调用 查找失败 则抛出异常
- 建议使用super() 调用方式 因为如果使用类名.方法名的方式 一旦类名发生更改 后期维护困难
-
使用
单继承
class A: name = '' def __init__(self, n): self.name = n def say(self): print('A类的say方法') class B(A): age = '' def __init__(self, n, a): # 第一种 通过类名调用 # A.__init__(self, n) # super 方法调用 super().__init__(n) self.age = a # 对于父类say方法的重写 def say(self): print('子类的say方法') def say1(self): # 第一种调用父类say方法 A.say(self) def say2(self): # 第二种调用父类say方法 super().say() b = B('lucky', 18) # print(b.age) # print(b.name) b.say()
多继承
class A: def say(self): print('A类的say方法') class B: def say(self): print('B类的say方法') class C(A, B): def say(self): # print('C类的say方法') # 第一种 类名调用父类方法 # B.say(self) # 使用super() 无参调用父类方法 # super().say() # 默认从左往右查 遇到就调用 # 使用super() 带参调用父类方法 # super(C, self).say() == super().say() super(A, self).say() # 从A类开始往右查找 # super(B, self).say() # AttributeError: 'super' object has no attribute 'say' c = C() c.say()
本文来自博客园,作者:寻月隐君,转载请注明原文链接:https://www.cnblogs.com/QiaoPengjun/p/16021576.html