其他分享
首页 > 其他分享> > 封装,继承,多态,继承的属性查找顺序,super()和mro()列表,多态与多态性

封装,继承,多态,继承的属性查找顺序,super()和mro()列表,多态与多态性

作者:互联网

image

一、面向对象的三大特征

1. 什么是继承?
	# 继承就是新建类的一种方式,新建的类我们称为子类或者叫派生类,被继承的类我们称为父类或者基类
     # 子类可以使用父类中的属性或者方法
2. 为什么要用继承?
	类解决了对象与对象之间的代码冗余问题
    继承解决的是类与类之间的代码冗余问题

3. 如何使用继承?
	新式类:继承了object类的子子孙孙类都是新式类
    经典类:没有继承了object类的子子孙孙类都是经典类
    
    # 新式类和经典类只有在python2中区分

继承:类与类之间的继承指的是什么’是’什么的关系(比如人类,猪类,猴类都是动物类)。子类可以继承/遗传父类所有的属性,因而继承可以用来解决类与类之间的代码重用性问题。比如我们按照定义Student类的方式再定义一个Teacher类

class Student:           # 定义学生类
    school = "南京校区"   # 冗余共同属性

    def __init__(self,name,age,gender):  # 学生类与老师类有冗余部分
        self.name = name
        self.age = age
        self.gender = gender

    def choose(self):
        print("%s 选课成功" %self.name)

stu1 = Student("jack",18,"male")
stu2 = Student("tom",19,"male")
stu3 = Student('lili',29,"female")

class Teacher:          # 定义老师类
    school = "南京校区"

    def __init__(self,name,age,gender,level):  # 老师类与学生类功能多一个level
        self.name = name
        self.age = age
        self.gender = gender
        self.level = level

    def score(self):
        print("%s 正在为学生打分" %self.name)

tea1 = Teacher('hxx',18,"male",10)
tea2 = Teacher('lxx',38,"male",3)

从上面看出:类Teacher与Student之间存在重复的代码,老师与学生都是人类,所以我们可以得出如下继承关系,实现代码重用

class Foo:
    def __f1(self):  # _Foo__f1()
        print('Foo.f1') # 2打印

    def f2(self):
        #
        print('Foo.f2') # 1 打印
        self.__f1()  # _Foo__f1()


class Bar(Foo):
    def __f1(self):  # # _Bar__f1()
        print('Bar.f1')
 '''
  会先从 自己本身Bar找f2  如果没有 ,就会去父类找,找到了f2  ,f2里面又执行了双下f1
 为隐藏属性,隐藏属性的特征 在定义的时候 就直接定义好了
'''

obj = Bar()  # {}
obj.f2()
# 新式类:按照广度优先查询
# 经典类:按照深度优先查询
class A(object):
    def test(self):
        print('from A')


class B(A):
    # def test(self):
    #     print('from B')
    pass

class C(A):
    # def test(self):
    #     print('from C')
    pass


class D(B):
    # def test(self):
    #     print('from D')
    pass

class E(C):
    # def test(self):
    #     print('from E')
    pass


class F(D, E):
    # def test(self):
    #     print('from F')
    pass


f1 = F()
f1.test()

1、继承的实现原理

Python中子类可以同时继承多个父类,如A(B,C,D)

如果继承关系为非菱形结构,则会按照先找B这一条分支,然后再找C这一条分支,最后找D这一条分支的顺序直到找到我们想要的属性

如果继承关系为菱形结构,那么属性的查找方式有两种,分别是:深度优先和广度优先

imgimg

二、super()和mro()列表

class People:
    school = "南京校区"

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

class Teacher(People):
    #            空对象,'hxx',18,"male",10
    def __init__(self,name,age,gender,level):
        # People.__init__(self,name,age,gender)
        super(Teacher,self).__init__(name,age,gender)

        self.level = level

    def score(self):
        print("%s 正在为学生打分" %self.name)


tea1 = Teacher('hxx',18,"male",10)  # 空对象,'hxx',18,"male",10
print(tea1.__dict__)


# 案例:
class A:  # [A,object]
    def test(self):
        print("from A")
        super().test()
class B:
    def test(self):
        print('from B')
class C(A,B):  # [C,A,B,object]
    pass

# obj=C()
# obj.test()

obj1 = A()
obj1.test()

image

三、多态与多态性

class Animal:    # 同一类事物:动物
  def talk(self):
        pass
    
class Dog(Animal):  # 动物的形态之一:狗
    def talk(self):       
        print("汪汪汪")

class Cat(Animal):  # 动物的形态之二:猫
    def talk(self):
        print('喵喵!')

class Pig(Animal):  # 动物的形态之一:猪
    def talk(self):
        print("哼哼哼!")

# 实例化得到三个对象
obj1 = Dog()
obj2 = Cat()
obj3 = Pig()

# 父类的功能是用来统一子类的,定标准的,只要看父类功能就知道子类也有
obj1.talk()
# 汪汪汪

obj2.talk()
# 喵喵!

obj3.talk()
# 哼哼哼!

1.更进一步,我们可以定义一个统一的接口来使用

def talk(animal):    # 定义一个函数talk 传进来参数就叫动物
    animal.talk()    # 只要是动物就肯定有talk方法

# 三个对象统一用一个函数talk去调,用起来统一了
talk(obj1)
talk(obj2)
talk(obj3)

综上我们得知,多态性的本质在于不同的类中定义有相同的方法名,这样我们就可以不考虑类而统一用一种方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有某些方法名

import abc
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod   # 该装饰器限制子类必须定义有一个名为talk的方法
    def talk(self): # 抽象方法中无需实现具体的功能
        pass

class Dog(Animal):  # 但凡继承Animal的子类都必须遵循Animal规定的标准
    def talk(self):
        print("汪汪汪")

class Cat(Animal):
    def talk(self):
        print('喵喵!')

class Pig(Animal): 
    def tell(self):  # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化
        print("哼哼哼!")

obj1 = Dog()
obj2 = Cat()
obj3 = Pig()

obj1.talk()
obj2.talk()
obj3.talk()
# 三者看起来都像,三者都有talk功能,然而它们并没有直接的关系,且互相独立

class Dog:
    def talk(self):  
        print("汪汪汪")

class Cat:
    def talk(self):
        print('喵喵!')

class Pig:
    def talk(self):
        print("哼哼哼!")

image

标签:继承,多态性,self,多态,def,子类,print,class,talk
来源: https://www.cnblogs.com/gengjian/p/15651698.html