我们都知道 Python 面向对象编程有三大特征, 继承, 封装和多态, 下面几篇问题, 我们会分别讲述着几大特征.
今天说的是继承, 如果有编程基础的人对这个词应该不会陌生, 继承是一种创建新类的方式, 新建的类可以继承一个或多个父类 (python 支持多继承), 父类又可称为基类或超类, 新建的类称为派生类或子类, 而子类会 ""遗传" 父类的属性 (数据属性和函数属性), 从而解决代码重用问题.
上面这段话就是继承的概念和使用继承所要达到的目的.
下面我们来看看具体代码案例, 继续的大致写法就是
子类名 (父类 1, 父类 2,...)
Python 是可以实现对继承的, 有些编程语法是只能单继承.
- class ParentClass:
- name= '父类'
- def __init__(self,size,color):
- self.size = size
- self.color = color
- def fun(self):
- print('我来自父类')
- class SubClass(ParentClass):
- name = '子类'
- pass
- # 实例化对象
- s1 = SubClass('30','red')
- #{'size': '30', 'color': 'red'} 如果子类没有构造方法的话, 子类属性会找到父类的构造方法, 继承父类的数据属性
- print(s1.__dict__)
- #(<class 'object'>,) python3 中统一都是新式类, 所以如果不加继承的父类, 默认的父类是 object 类
- print(ParentClass.__bases__)
- #(<class '__main__.ParentClass'>,) 子类的父类
- print(SubClass.__bases__)
- # "我来自父类" 子类对象调用父类的方法
- s1.fun()
- # 子类对象调用数据属性, 会先在子类中找, 如果找不到会去父类的作用域里面找
- # 这里子类里面定义了 name 属性所以结果是: 子类
- # 如果子类里面没有定 name, 结果就是: 父类
- print(s1.name)
这段是继承大致的用法, 子类可以继承父类的数据属性和函数属性. 下面我们说说使用继承的好处及代码重用和重写, 组合的用法
- class Cat:
- def cry(self):
- print('喵喵')
- def eat(self):
- print('吃')
- def run(self):
- print('跑')
- def jump(self):
- print('跳')
- class Dog:
- def cry(self):
- print('汪汪')
- def eat(self):
- print('吃')
- def run(self):
- print('跑')
- def jump(self):
- print('跳')
- cat1 = Cat()
- dog1 = Dog()
- cat1.cry()
- dog1.cry()
- class animal:
- def cry(self):
- print('动物叫')
- def eat(self):
- print('吃')
- def run(self):
- print('跑')
- def jump(self):
- print('跳')
- class Cat(animal):
- def cry(self):
- print('喵喵')
- class Dog(animal):
- def cry(self):
- print('汪汪')
- cat1 = Cat()
- dog1 = Dog()
- cat1.cry() #喵喵
- dog1.cry() #汪汪
- cat1.eat() #吃
- dog1.eat() #吃
- class animal:
- def cry(self):
- print('动物叫')
- def eat(self):
- print('吃')
- def run(self):
- print('跑')
- def jump(self):
- print('跳')
- class Cat(animal):
- def cry(self):
- print('喵喵')
- class Dog(animal):
- def cry(self):
- print('汪汪')
- cat1 = Cat()
- dog1 = Dog()
- cat1.cry() #喵喵 重写父类 cry 方法
- dog1.cry() #汪汪 重写父类 cry 方法
- class animal:
- def cry(self):
- print('动物叫')
- def eat(self):
- print('吃')
- def run(self):
- print('跑')
- def jump(self):
- print('跳')
- class Cat(animal):
- def cry(self):
- print('喵喵')
- def swoop(self): #定义子类的方法
- print('飞扑')
- cat1 = Cat()
- cat1.swoop()
- class School:
- def __init__(self,name,addr):
- self.name=name
- self.addr=addr
- def recruit(self):
- print('%s xxx 计算机学校正在招生' %self.name)
- class Course:
- def __init__(self,name,price,period,School):
- self.name=name
- self.price=price
- self.period=period
- self.school=School #实现 Course 和 School 的组合
- s1=School('xxx 计算机学校','北京')
- s2=School('xxx 计算机学校','南京')
- s3=School('xxx 计算机学校','上海')
- msg='''
- 1 xxx 计算机学校 北京校区
- 2 xxx 计算机学校 南京校区
- 3 xxx 计算机学校 上海校区
- '''
- while True:
- print(msg)
- menu={
- '1':s1,
- '2':s2,
- '3':s3
- }
- choice=input('选择学校 >>:')
- school_obj=menu[choice]
- name=input('课程名 >>:')
- price=input('课程费用 >>:')
- period=input('课程周期 >>:')
- new_course=Course(name,price,period,school_obj)
- print('课程 [%s] 属于 [%s] 学校' %(new_course.name,new_course.school.name)) #实现 Course 和 School 的组合
- import abc #利用 abc 模块实现抽象类
- class Interface(metaclass=abc.ABCMeta):
- @abc.abstractclassmethod #抽象方法, 不做具体实现
- def test1(self):
- pass
- @abc.abstractclassmethod
- def test2(self):
- pass
- class SubClass(Interface):
- def test1(self):
- print('实现抽象方法 1')
- def test2(self):
- print('实现抽象方法 2')
- s1 = SubClass()
- import abc #利用 abc 模块实现抽象类
- class Interface(metaclass=abc.ABCMeta):
- @abc.abstractclassmethod #抽象方法, 不做具体实现
- def test1(self):
- pass
- @abc.abstractclassmethod
- def test2(self):
- pass
- class SubClass(Interface):
- def test1(self):
- print('实现抽象方法 1')
- # 不实现 test2 方法
- s1 = SubClass()
- class A:
- def test(self):
- print('A')
- class B(A):
- def test(self):
- print('B')
- class C(A):
- def test(self):
- print('C')
- class D(B):
- def test(self):
- print('D')
- class E(C):
- def test(self):
- print('E')
- class F(D,E):
- def test(self):
- print('F')
- # (<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
- print(F.__mro__)
- class animal:
- def __init__(self,name,type,size,color):
- self.name = name
- self.type = type
- self.size = size
- self.color = color
- def cry(self):
- print('动物叫')
- def eat(self):
- print('吃')
- class Cat(animal):
- def __init__(self,name,type,size,color,age):
- super().__init__(name,type,size,color) #调用父类的构造函数, 这是 super 最常用的地方
- self.age = age
- def cry(self):
- super().cry() #子类重新了父类的方法, 但是同时又要实现父类中 cry 方法
- print('喵喵')
- cat1 = Cat('毛球','波斯猫',10,'白色','5 岁')
- # 动物叫
- # 喵喵
- cat1.cry()
来源: http://www.jianshu.com/p/08b26086bd62