python-面向对象(三)
类的继承
概念
1. 什么是继承?
继承就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类
子类可以使用父类中的属性或者方法
2. 为什么要用继承?
类解决了对象与对象之间的代码冗余问题
继承解决的是类与类之间的代码冗余问题
3. 如何使用继承?
新式类:继承了object类的子子孙孙类都是新式类
经典类:没有继承了object类的子子孙孙类都是经典类
# 新式类和经典类只有在python2中区分
# python2中是经典类
使用继承
class People:
school = 'SH'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
class Student(People):
def __init__(self, name, age, gender, course=None):
People.__init__(self, name, age, gender)
self.course = course
class Teacher(People):
def __init__(self, name, age, gender, level):
# People.__init__(self, name, age, gender)
super().__init__(name, age, gender)
self.level = level
def score(self, stu_obj, score):
stu_obj.score = score
s1 = Student('mjc', 99, 'male')
t1 = Teacher('jason', 18, 'male', 100)
print(s1.name)
t1.score(s1, 90)
print(s1.score)
单继承下的属性查找
class Foo:
def f1(self):
print('from Foo:f1')
def f2(self):
print('from Foo:s2')
self.f1() # 从对象本身开始再出发,所以从Bar类中的 f1
class Bar(Foo):
def f3(self):
print('from Bar:f3')
def f1(self):
print('from Bar:f1')
obj = Bar()
obj.f2()
# from Foo:s2
# from Bar:f1
多继承下的属性查找(菱形问题)

class A(object):
def test(self):
print('from A')
class B(A):
def test(self):
print('from B')
class C(A):
def test(self):
print('from C')
class D(B):
def test(self):
print('from D')
class E(C):
def test(self):
print('from E')
class F(D,E):
# def test(self):
# print('from F')
pass
f1=F()
f1.test()
print(F.__mro__) # 只有新式才有这个属性可以查看线性列表,经典类没有这个属性
print(F.__bases__) # 查看继承了哪些父类
#新式类继承顺序:F->D->B->E->C->A
#经典类继承顺序:F->D->B->A->E->C
#python3中统一都是新式类
#pyhon2中才分新式类与经典类
mro列表
class A:
def test(self):
print('from A:test')
super().test()
class B:
def test(self):
print('from B:test')
class C(A, B):
# def test(self):
# print('from C:test')
pass
s = C()
s.test()
print(C.__mro__)
# from A:test
# from B:test
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
super()
# 用于调用父类的一个方法
多态与多态性
抽象类
# 抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def talk(self):
pass
class People(Animal):
# pass # 这个地方必须定义 talk 抽象方法 如果没定义实例化就会报错
def talk(self):
print('哈哈哈')
c = People()
多态
# 定义时的类型和运行时的类型不一样,就称为多态。
class Pig():
def talk(self):
print('哼哼哼')
class Dog():
def talk(self):
print('汪汪汪')
# dog、pig都是动物,只要是动物肯定有talk方法
# 于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
obj1 = Pig()
obj2 = Dog()
鸭子类型
动态语言调用实例方法时不检查类型,只要方法存在,参数正确,就可以调用。这就是动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
def len1(a):
return a.__len__()
s = 'test'
l = ['1', '2']
len1(s)
len1(l)
父类限制子类
# 父类限制子类的行为
class Animal():
def speak(self):
raise Exception("必须实现speak方法")

浙公网安备 33010602011771号