面向对象第三讲
单继承下的属性查找
# 案例1
class Foo():
def f1(self):
print(‘from.f1‘)
def f2(self):
print(‘from .f2‘)
self.f1()
class Bar(Foo):
def f1(self):
print(‘Bar.f1‘)
obj = Bar()
obj.f2()
======================>
from .f2
Bar.f1
# 案例2
class Foo():
def __f1(self): # _Foo__f1()
print(‘from.f1‘)
def f2(self):
print(‘from .f2‘)
self.__f1()
class Bar(Foo):
def __f1(self): # _Bar__f1()
print(‘Bar.f1‘)
obj = Bar()
obj.f2()
======================>
from .f2
from.f1
"""
单继承下的属性查找,对象---> 类---> 父类
"""
多继承下的属性查找
菱形继承:
非菱形继承:
python3里面都是新式类
super与mro方法
super是继承下属性查找的另外一种方法,详细看我博客
class People():
def __init__(self, name, age):
self.name = name
self.age = age
class Student(People):
def __init__(self, name, age, gender):
# super(People, self).__init__(name, age) python2这样写
super().__init__(name, age)
self.gender = gender
obj = Student(‘lyh‘, 10, ‘male‘)
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()
print(C.__mro__)
=============================>
(<class ‘__main__.C‘>, <class ‘__main__.A‘>, <class ‘__main__.B‘>, <class ‘object‘>)
多态
import abc
class Animal():
@abc.abstractmethod
def speak(self):
pass
class People(Animal):
def speak(self):
print(‘makbak‘)
class Dog(Animal):
def speak(self):
print(‘汪汪汪‘)
obj = People()
obj.speak()
"""
多态类中的继承:不是让子类来继承父类的属性和方法的,而是用来给子类定制标准的
多态带来的特性: 在不用考虑对象数据类型的情况下,直接调用对象的方法
"""
# 错误示范
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass
class People(Animal):
def speak(self):
print(‘makbak‘)
class Dog(Animal):
def speak(self):
print(‘汪汪汪‘)
class Pig(Animal):
pass
obj = Pig() # TypeError: Can‘t instantiate abstract class Pig with abstract methods speak
# 对多态特性的应用
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass
class People(Animal):
def speak(self):
print(‘makbak‘)
class Dog(Animal):
def speak(self):
print(‘汪汪汪‘)
class Pig(Animal):
def speak(self):
print(‘woll‘)
obj = Pig()
def animal(animal):
return animal.speak()
animal(obj)
# 调用这个animal方法的时候,可以不用考虑对象是否有这个方法,因为用抽象类实例化出的方法肯定有这个类
多态性的优点:
1.增加了程序的灵活性
2. 增加了程序的可扩展性(比如,上面的抽象类animal,不管我们怎么去继承这个抽象类,使用者都无须关注,因为只要继承了animal肯定有speak这个方法)
鸭子类型:
鸭子类型就是只要他们有相同的属性和功能那就是一样的,即”看起来像鸭子,走路像鸭子,那他就是鸭子“
比如文件,只要都有读和写的功能,那他就是文件
案例一:
#str,list,tuple都是序列类型
s=str(‘hello‘)
l=list([1,2,3])
t=tuple((4,5,6))
#我们可以在不考虑三者类型的前提下使用len
s.__len__()
l.__len__()
t.__len__()
len(s)
len(l)
len(t)
组合
"""
组合: 一个对象拥有一个属性,该属性是另外一个对象
解决类与类之间代码冗余的问题:
1.继承:满足什么是什么的关系
2.组合:满足什么有什么的关系
"""
"""
需求:
定义学生,课程类
让学生可以选择课程,课程由课程类实例化得到
"""
class Student():
def __init__(self, name, age):
self.name = name
self.age = age
self.course_list = []
def add_course(self, course_obj):
self.course_list.append(course_obj)
class Course():
def __init__(self, course_name, course_period, course_price):
self.course_name = course_name
self.course_period = course_period
self.course_price = course_price
python = Course(‘python‘, 6, 100000)
stu1 = Student(‘egon‘, 10)
stu1.add_course(python)
print(stu1.name, stu1.course_list[0].course_name)