目录:面向对象的三大特征:封装、继承、多态
1.继承
2、继承的属性查找:
单继承下的属性查找
多继承下的属性查找
3.super和mro列表
4.多态
一、继承
1.什么是继承:继承是一种创建新类的方式,新建出来的类我们称之为子类或者派生类,被继承的类称之为父类或者基类
2.为何要用继承:
类解决的是对象与对象之间的代码冗余问题
继承解决的是类与类之间的代码冗余问题
3.如何使用继承
新式类:继承了object类的子子孙孙类都是新式类
经典类:不继承object类的子子孙孙类都是经典类
新式类和经典类只在python2中区分
在python3中都是新式类
4.子类如何使用父类的属性
(1)、指名道姓:People.__init__(self,name,age,gender)
(2)、super()
class Parent1(object): pass class Parent2(object): pass class Sub1(Parent1): pass class Sub2(Parent1, Parent2): pass print(Parent1.__bases__) print(Parent2.__bases__) print(Sub1.__bases__) print(Sub2.__bases__)
执行结果
(<class 'object'>,)
(<class 'object'>,)
(<class '__main__.Parent1'>,)
(<class '__main__.Parent1'>, <class '__main__.Parent2'>)
提示:如果没有指定基类,python的类会默认继承object类,object是所有python类的基类,它提供了一些常见方法(如__str__)的实现。
class People(): school = 'SH' def __init__(self, name, age, gender): # self => stu self.name = name self.age = age self.gender = gender class Student(People): def __init__(self, name, age, gender, course=None): if course is None: course = [] self.courses = course # self => stu People.__init__(self, name, age, gender) # 普通方法, 指名道姓的调用方法 def choose_course(self, course): # stu_dic['course'].append(course) # stu_obj['course'].append(course) # stu_obj.courses.append(course) # self.courses.append(course) self.courses.append(course) print("%s选课成功%s" % (self.name, self.courses)) stu = Student('egon', 19, 'male') # Student(stu, 'egon', 19, 'male') # print(stu.school) # print(stu.name) # print(stu.age) # print(stu.gender) class Teacher(People): def __init__(self, name, age, gender, level): self.level = level People.__init__(self, name, age, gender) # 普通方法, 指名道姓的调用方法 def score(self, stu_obj, score): stu_obj.score = score print("%s给%s打了%s分" % (self.name, stu_obj.name, score)) tea = Teacher('ly', 18, 'male', 10) print(tea.name) print(tea.age) print(tea.level)
2.继承的属性的查找
(1)单继承下属性的查找
class Foo: def f1(self): print("foo.f1") def f2(self): print("foo.f2") self.f1() #self=>obj class Bar(Foo): def f1(self): print("Bar.f1") obj=Bar() obj.f2()
执行结果
foo.f2
Bar.f1
class Foo: def __f1(self): #def _Foo__f1() print("foo.f1") def f2(self): print("foo.f2") self.__f1() #self._Foo__f1() class Bar(Foo): def __f1(self): #def _Bar__f1() print("Bar.f1") obj=Bar() obj.f2() 执行结果 foo.f2 foo.f1
(2)多继承下的属性查找
class G(object): # def test(self): # print('from G') pass class F(G): # def test(self): # print('from F') pass class C(F): # def test(self): # print('from C') pass class D(G): # def test(self): # print('from D') pass class E(G): # def test(self): # print('from E') pass class H(): def test(self): print('from H') pass class B(E, H): # def test(self): # print('from B') pass class A(B, C, D): # def test(self): # print('from A') pass # f1 = A() # f1.test() # print(A.__mro__) f1 = E() # f1.test() print(E.__mro__)
3.super与mro列表
# class People(): # school = 'SH' # # def __init__(self, name, age, gender): # # self => stu # self.name = name # self.age = age # self.gender = gender # # # class Student(People): # def __init__(self, name, age, gender, course=None): # if course is None: # course = [] # self.courses = course # # self => stu # # People.__init__(self, name, age, gender) # 普通方法, 指名道姓的调用方法 # # super(Student, self).__init__(name, age, gender) # python2 super(Student, self) 返回的是一个特殊的对象 # super().__init__(name, age, gender) # python3 super(Student, self) 返回的是一个特殊的对象 # # 他遵从mro列表 # def choose_course(self, course): # self.courses.append(course) # print("%s选课成功%s" % (self.name, self.courses)) # # # stu = Student('egon', 18, 'male') # print(stu.name) # print(stu.age) # print(stu.gender) # # class Teacher(People): # def __init__(self, name, age, gender, level): # self.level = level # People.__init__(self, name, age, gender) # 普通方法, 指名道姓的调用方法 # # def score(self, stu_obj, score): # stu_obj.score = score # print("%s给%s打了%s分" % (self.name, stu_obj.name, score))
# A没有继承B,但是A内super会基于C.mro()继续往后找 # class A: # def test(self): # print("A.test") # super().test() # # # class B: # def test(self): # print('from B') # # # class C(A, B): # pass # # # c = C() # c.test() # 打印结果:from B # print(C.mro()) class A: def test(self): print('A---->test') super().aaa() class B: def test(self): print('B---->test') def aaa(self): print('B---->aaa') class C(A, B): def aaa(self): print('C----->aaa') # c = C() # c.test() # 打印结果: # print(C.__mro__) a = A() # a.test() print(A.__mro__)
4.多态与多态性
多态指的是一类事物有多种状态
水:固态、液态、气态
动物有多种形态:人、狗、猪
继承:子类使用父类的属性
多态带来的特性:在不考虑对象的数据类型的情况下,直接调用方法
#抽象类只能被继承,不能被实例化
import abc #abstract 抽象类 class Animal(metaclass=abc.ABCMeta): #同一类事物:动物 @abc.abstractmethod #抽象方法 def talk(self): pass class People(Animal): #动物的形态之一:人 def talk(self): print('say hello') class Dog(Animal): #动物的形态之二:狗 def talk(self): print('say wangwang') class Pig(Animal): #动物的形态之三:猪 def talk(self): print('say aoao')
python中不推荐上面的写法,推荐下面的写法
class People():
def talk(self):
print('say hello')
pass
class Dog():
def talk(self):
print('say wangwang')
pass
class Pig():
def talk(self):
print('say aoao')
pass
obj1=People()
obj1=Dog()
obj1=Pig()
#obj1.speak()
def animal(animal):
return animal.speak()
animal(obj1)
peo=People() dog=Dog() pig=Pig() #peo、dog、pig都是动物,只要是动物肯定有talk方法 #于是我们可以不用考虑它们三者的具体是什么类型,而直接使用 peo.talk() dog.talk() pig.talk() #更进一步,我们可以定义一个统一的接口来使用 def func(obj): obj.talk()
多态性:分为静态多态性与动态多态性
静态多态性:如任何类型都可以用运算符+进行运算