单继承下的属性查找
# 案例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(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这个方法)
鸭子类型:
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这个方法)
组合
""" 组合: 一个对象拥有一个属性,该属性是另外一个对象 解决类与类之间代码冗余的问题: 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)