90s-blog

1.面向对象的三大特征

# 面向对象的三大特征:封装、继承、多态

2.类的继承

1.什么是继承?
	继承是新建类的一种方式,新建的类被称为子类或者派生类,被继承的类被称为父类或者基类。
2.为什么要用继承
	子类可以使用父类的属性和方法。
    类解决了对象与对象之间代码冗余的问题
    继承解决了类与类之间代码冗余的问题。
3.继承的分类:
	经典类:没有继承object类的子子孙孙类的都属于经典类
    新式类:继承了object类的子子孙孙类的都属于新式类。
    
    # 在python2中才有经典类和新式类之分,在python3中都是新式类。

4.查看父类
print(子类名.__bases__)
    
5.类的继承
# 以学生选课系统为例:
# 定义一个公共的类,把学生类和老师类里面 一样的东西拿出来
class People():
    school = \'老男孩\'
    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):
        if course is None:
            course = []
        People.__init__(self, name, age, gender)
        self.course = course

    def choose_course(self, course):
        self.course.append(course)
        print(\'%s选课成功%s\' % (self.name, course))
# 调用类产生对象
stu1 = Student(\'qql\', 18, \'female\', \'python\')
print(stu1.name)
# 老师类
class Teacher():
    def __init__(self, name, age, gender, level):
        People.__init__(self, name, age, gender)
        self.level = level
    def score(self, stu_obj, score):
        stu_obj.score = score
        print(\'%s给%s打了%s分\' % (self.name, stu_obj.name, score))
t1 = Teacher(\'jason\', 20, \'male\', 10)
print(t1.name)
t1.score(stu1, 80)

image-20211206160822980

image-20211206175524815

3.单继承下的属性查找

有了继承关系后,对象在查找属性的时候,会先在自己的__dict__里面查找,如果找不到,就去产生自己的子类里面找,如果再找不到,就会去父类里面找。

# 举例
class Foo:
    def f1(self):
        print(\'Foo.f1\')

    def f2(self):
        print(\'Foo.f2\')
        self.f1()


class Bar(Foo):
    def f1(self):
        print(\'Bar.f1\')


obj = Bar()  # 没有传入参数的生成的对象就是一个空字典  {}
obj.f2()  # 要确认到底self是谁


# 练习 父类如果不想让子类覆盖自己的方法,可以采用隐藏方法设置成自己私有的

class Foo:
    def __f1(self):  # _Foo__f1()  # 隐藏属性对外不对内
        print(\'Foo.f1\')

    def f2(self):
        print(\'Foo.f2\')
        self.__f1()  # _Foo__f1()  指名道姓的拿


class Bar(Foo):
    def __f1(self):  # _Bar__f1()
        print(\'Bar.f1\')


obj = Bar()  # 没有传入参数的生成的对象就是一个空字典  {}
obj.f2()  # 要确认self到底是谁


image-20211206162251724

image-20211206162805826

4.多继承下的属性查找

1.经典类(菱形问题)(了解)--深度优先
如果继承多个类,从左往右查找。左边分支到最深后,到左二分支...

# 经典类:深度优先
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, C):
    pass

obj = D()
obj.test()

2.新式类(分支不相交)--广度优先
在父类从左右到查找,先不查到最深的那个
查到最右边的父类再到最深那个
# 新式类:广度优先
class A(object):
    def test(self):
        print(\'from A\')
class B(A):

    pass
class C(A):

    pass
class D(B):

    pass
class E(C):

    pass
class F(D, E):

    pass
f1 = F()
f1.test()


image-20211206164957311

image-20211206165716845

5.关键字super()和mro()

调用super()会得到一个特殊的对象,该对象专门用来引用父类的属性,并且严格按照C3线性(mro)的顺序向后查找。使用时会自动传入self参数,不能在写,否则参数多了。

Python 2 中: super(自己的类名, self).__init__( 参数1, 参数2 ···) 完整写法。
Python 3 中:  super().__init__( 参数1, 参数2 ···) 简写。

class People():
    school = \'SH\'

    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender


class Teacher(People):
    def __init__(self, name, age, gender, level):
        self.level = level
        super().__init__(name, age, gender)  # super的使用:按照C3线性查找


print(Teacher.__mro__)  # C3线性 : (<class \'__main__.Teacher\'>, <class \'__main__.People\'>, <class \'object\'>)
t1 = Teacher(\'qql\', 20, \'male\', 10)


# 练习
# mro列表练习1
class A():
    def test(self):
        print(\'from A.test\')
        super().test()

class B:
    def test(self):
        print(\'from B\')

class C(A, B):
    pass

c = C()
c.test()
print(C.__mro__)  # 查看C3线性


# mro列表练习2
class B:
    def test(self):
        print(\'B---->test\')
    def xixi(self):
        print(\'B---->aaa\')

class A:
    def test(self):
        print(\'A---->test\')
        super().xixi()

class C(A, B):
    def aaa(self):
        print(\'C----->aaa\')
c = C()
c.test()
print(C.mro())  # 查看C的C3线性继承



image-20211206172525225

image-20211206184245337

6.多态与多态性与鸭子类型

1.什么是多态
	多态即事物的多种状态
    
2. # 抽象类只能被继承,不能被实例化
	导入abc模块,在父类体代码中方法的顶上紧贴着使用@abc.abstractmethod,会把该方法变成抽象方法,抽象方法体中不能写代码,只能写pass;子类体代码中必须要有一样的方法名来实现,否则就会报错,这种方法在python中不推荐使用。

import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod  # 紧贴着的下面那个方法变成抽象方法,也就是说子类必须有该方法实现
    def speak(self):  
        pass  # 抽象方法体不能写代码,只能写pass
    @abc.abstractmethod  # 紧贴着的下面那个方法变成抽象方法,也就是说子类必须有该方法实现
    def login(self):  
        pass  # 抽象方法体不能写代码,只能写pass
# a1 = Animal()  实例化会报错
class People(Animal):
    def speak(self):
        print(\'嗷嗷嗷\')
    def login(self):
        pass
class Pig(Animal):
    def speak(self):
        print(\'哼哼哼\')
    def login(self):
        pass
class Dog(Animal):
    def speak(self):
        print(\'汪汪汪\')

obj = People()
obj.speak()

3. # 多态推荐用法--鸭子类型
	定义一个有参函数,传入对象返回值 对象.方法名()

# 例子
# 多态练习
class Pig():
    def speak(self):
        print(\'哼哼哼\')
class Dog():
    def speak(self):
        print(\'汪汪汪\')
class Txt():
    def speak(self):
        print(\'Txt\')
# 定义一个有参函数,传入对象返回对象.方法名()
def animal(animal):
    return animal.speak()
# 调用类产生对象
obj1 = Pig()
obj2 = Dog()
obj3 = Txt()
# 多态带来的特性:在不用考虑对象数据类型的情况下,可以直接调用对应的函数
animal(obj1)  # obj1.speak()
animal(obj2)  # obj2.speak()
animal(obj3)  # obj3.speak()


4. # 父类限制子类的行为
	父类有该方法,用raise主动报错限制子类必须有该方法,如果子类没有的话,找到父类那里就会主动报错。
class Animal():
    def speak(self):
        # 主动报错:如果子类里面没有该方法又想用父类的方法,就会报错
        raise Exception("必须实现speak方法")
class Pig(Animal):
    def speak(self):
        print(\'哼哼哼\')
class Dog(Animal):
    school = \'老男孩\'
    print(school)
class Txt(Animal):
    def speak(self):
        print(\'Txt\')

obj1 = Dog()
obj1.speak()

5.鸭子类型(duck teying)
	不依赖于继承,只需要制造出外观和行为相同对象,同样可以实现不考虑对象类型而使用对象。这正是Python崇尚的“鸭子类型”(duck typing):“如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”。比起继承的方式,鸭子类型在某种程度上实现了程序的松耦合度。
    
#二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系
class Txt: #Txt类有两个与文件类型同名的方法,即read和write
    def read(self):
        pass
    def write(self):
        pass

class Disk: #Disk类也有两个与文件类型同名的方法:read和write
    def read(self):
        pass
    def write(self):
        pass

image-20211206185816258

image-20211206191008586

image-20211206191646053

分类:

技术点:

相关文章: