面向对象第三讲

单继承下的属性查找

# 案例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
"""
单继承下的属性查找,对象---> 类---> 父类
"""

多继承下的属性查找

菱形继承:

面向对象第三讲_多态

面向对象第三讲_python_02

非菱形继承:

面向对象第三讲_子类_03

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)