首页 > 其他分享 >单继承、多继承下的属性查找、super关键字、多态与多态性、组合

单继承、多继承下的属性查找、super关键字、多态与多态性、组合

时间:2023-06-27 20:35:13浏览次数:39  
标签:obj 继承 多态性 self 多态 查找 print class def

单继承下的属性查找

单继承:一个类只能继承一个类。

class C():
pass
class B(C):
    pass
class A(B): # 单继承
    pass

单继承下的属性查找顺序:

  先从对象本身的名称空间中查找 ------> 产生这个对象的类中去查找 ------>继承的父类中去查找

# 查找属性
class Foo():
    def f1(self):
        print('from f1')

    def f2(self):
        print('from f2')
        self.f1() # 此时,self = obj,所以调用Bar中的方法'f1'

class Bar(Foo): # 单继承,继承Foo的所有属性
    def f1(self):
        print('from Bar')

obj = Bar() # 调用Bar产生一个 obj对象
obj.f2()  # obj.f2() = obj.f2(obj)  # from f2
                                    # from Bar

练习题

class Foo():
    def __f1(self): # 隐藏方法 _Foo__f1
        print("Foo.f1")

    def f2(self):
        # obj:
        print("Foo.f2")
        self.__f1() # self._Foo__f1()

class Bar(Foo):
    def __f1(self):
        print("Bar.f1")
obj = Bar()
obj.f2()  # obj.f2(obj) # Foo.f2
                        # Foo.f1

多继承下的属性查找

多继承:一个类可以继承多个类,从左往右依次查找(python中支持多继承)

class D():
    pass
class C(D):
    pass
class B(C,D):
    pass
class A(B,C,D):
    pass

多继承下的属性查找分为:菱形查找、非菱形查找

  经典类:按深度优先查找

  新式类:按广度优先查找

# 多继承下的属性查找
class F():
    def f(self):
        print('from F')
class E():
    def f(self):
        print('from E')
class D(F):
    def f(self):
        print('from D')
class C(E):
    ...
    # def f(self):
    #     print('from C')
class B():
    ...
    # def f(self):
        # print('from B')
class A(B,C,D):
    # def f(self):
        # print('from A')
    ...
obj = A()
print(A.mro()) # mro 打印出查找顺序
# 查找顺序:[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.D'>, <class '__main__.F'>, <class 'object'>]
obj.f() # from E
# 广度查找
class G(object):
    def test(self):
        print('from G')
class E(G):
    def test(self):
        print('from E')
class F(G):
    def test(self):
        print('from F')
class B(E):
    def test(self):
        print('from B')
class C(F):
    def test(self):
        print('from C')
class D(G):
    def test(self):
        print('from D')
class A(B, C, D):
    # def test(self):
    #     print('from A')
    pass

obj = A()
print(A.mro())  # 打印A类的mro顺序
# [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]

在python3 中都是新式类,所以多继承下的属性查找,如果属性查找不到,按广度优先的方式继续查找。

一般情况下,最好不使用多继承。

super关键字

super关键字的使用:当一个类没有继承另一个类的时候,继续按照mro列表来查找属性

# super关键字的使用
class A():
    def f(self):
        super().f() #在A没有继承B的时候,继续按照mro列表继续往后走

class B():
    def f(self):
        super().f() # 在B类没有继承C类,继续往下执行
class C():
    def f(self):
        print('C')

class D(A,B,C):
    pass

obj = D()
print(D.mro()) #[<class '__main__.D'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
obj.f()  # C

多态与多态性

多态:一种事物的多种形态

多态性:多态带来的特性,就是在不考虑对象的类型的情况下,直接调用对象的方法。

多态性的例子:

def len():
    return obj.len()
len('123')
len([1,2,3])
len({'a':1})
len((1,2,3))
# 鸭子类型
class People():
    def speak(self):
        print('People')
class Cat():
    def speak(self):
        print('Cat')
class Dog():
    def speak(self):
        print('Dog')
class Flower():
    def f(self):
        print('Flower')
obj = People()
obj1 = Cat()
obj2 = Dog()
obj3 = Flower()
# 定义一个功能用来执行共有的功能
def Animal(obj):
    return obj.speak()
Animal(obj)  #People
Animal(obj1) #Cat
Animal(obj2) #Dog
Animal(obj3) # 没有speak这个功能所以会报错 AttributeError: 'Flower' object has no attribute 'speak'

强制限制(不推荐):

  通过在父类导入 abc模块,将类抽象化,从而限制子类必须要有某些方法。

抽象类的特点:只能被继承,不能被实例化。抽象类中的方法都是抽象方法,抽象方法不会实现具体的功能,只是用来限制子类的行为。

# 强制限制
import abc
class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
    def speak(self):  # 抽象方法中无需实现具体的功能
        pass
    def eat(self):
        pass

class cat(Animal):
    def speak(self):
        print('cat speak miao')
    def eat(self):
        print('cat eat fish')
class pig(Animal):
    def sleep(self):
        print('pig always sleep')
obj = cat()
# 若子类pig中没有一个名为talk的方法则会抛出异常TypeError,无法实例化。
obj1 = pig()  # TypeError: Can't instantiate abstract class pig with abstract methods speak
obj.speak() # cat speak miao
obj.eat() # cat eat fish
# pig 类中没有speak方法,而在父类Animal中speak方法被抽象化了,所以子类中必须要定义speak方法
# obj1.sleep() # TypeError: Can't instantiate abstract class pig with abstract methods speak

组合

组合:就是一个对象拥有一个属性,该属性的值是另外一个对象

class Foo():
    def __init__(self,m):
        self.m = m
class Bar():
    def __init__(self,n):
        self.n = n
obj = Foo(10)
obj1 = Bar(20)
obj.x = obj1  # 组合,此时的obj就是一个超级对象,通过一个对象得到另外一个对象的值
print(obj.x.n) # obj.x 就是 obj1  结果为:20
class People():
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

"""
继承一般用在什么是什么的时候
组合一般用在什么有什么的时候
"""
class Course():
    def __init__(self, course_name, course_price, course_period):
        self.course_name = course_name
        self.course_price = course_price
        self.course_period = course_period

python=Course("python", 10000, '6mon')
linux = Course("linux", 20000, '5mon')
# print(python.course_name) # python


class Student(People):
    def __init__(self, name, age, gender, course=None):
        if course is None:
            course = []
        super().__init__( name, age, gender) # 调用People里的__init__
        self.courses = course
    def choose_course(self):
        pass


stu = Student('kevin', '19', 'male')

stu.courses.append(python) # stu.courses ====> [python对象]
stu.courses.append(linux) # stu.courses ====> [python对象, linux对象]
print(stu.courses) # [<__main__.Course object at 0x00000149EE630940>, <__main__.Course object at 0x00000149EE630A20>]
for i in stu.courses:
    print(i.course_name)
    print(i.course_price)
# 结果为:
# python
# 10000
# linux
# 20000

 

标签:obj,继承,多态性,self,多态,查找,print,class,def
From: https://www.cnblogs.com/Lucky-Hua/p/17508920.html

相关文章

  • python基础33 继承、组合
    单继承下的查找循序单继承的意思是一个类只继承一个类classD():passclassC(D):passclassB(C):passclassA(B):pass如何查找继承下的属性和方法呢classFoo():def__f1(self):#_Foo__f1()print("Foo.f1")deff2(self):......
  • 继承(下)
    继承中构造方法的访问特点子类在初始化之前必须先初始化父类。即在调用子类的构造方法之前必须调用父类的构造方法。因为子类里面的有部分属性和方法使用的父类的,必须将父类的方法和属性初始化,子类才可以拿来使用(有父才有子)我们的父类中会有JVM隐藏添加的空参构造方法classPer......
  • 继承(上)
    继承入门初级信息关系系统的缺陷问题:我们的学生类和老师类中有很多相同的代码(代码重复冗余)将student和teacher类相同的属性和方法抽取成一个专门的父类Person学到这里的话,我们可以将我的信息管理系统进行优化:将student和teacher共同代码抽取成一个Person类,继承的概述......
  • c++中虚析构函数如何实现多态的、内存布局如何?
    作者:冯Jungle链接:https://www.zhihu.com/question/36193367/answer/2242824055来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。之前Jungle写过一篇文章《探究C++:虚函数表究竟怎么回事?》,主要通过测试代码来验证虚函数表的存在,进而说明C++的多态机制......
  • Ts中的多态
    //父类定义一个方法不去实现,让继承它的子类去实现,每一个子类有不同的表现多态属于继承classAnimal{   name:string   constructor(name:string){       this.name=name   }   eat(){       console.log('吃的方法')   }}class......
  • Android-kotlin-接口与多态的表现
    上一篇博客介绍了Android-Kotlin-抽象类与多态的表现;而这一篇博客专门介绍下接口与多态的表现1.选择包名,然后右键:2.选择Class类型,会有class:3.选择File类型,不会自动有class:5.选择interface,是创建接口:6.目录结构:1.定义手机充电接口标准规范InterfacePhone:packagecn.kotlin.kot......
  • Android-kotlin的继承
    上一篇博客讲了Android-kotlin的配置/入门,然后简单的实现了一个计算器功能。今天我们来讲讲kotlin中的继承是怎样的。1.先看一个案例,子类使用到父类的资源【案例一】父类张翠山:packagecn.kotlin.kotlin_oop03/***描述父对象:张翠山**personDescribe此人的简介/var......
  • 【python基础】类-继承
    编写类时,并非总是要从空白开始。如果要编写的类时另一个现成类的特殊版本,可使用继承。一个类继承另一个类时,它将自动获得另一个类的所有属性和方法原有的类称为父类,而新类被称为子类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。继承语法格式:class子类......
  • ES5和ES6的继承
    (1)ES5//构造函数functionPerson(name){this.name=name}//原型Person.prototype.say=function(){console.log('我是'+this.name)}//子类构造函数继承父类构造函数functionSon(name,age){//调用父类构造函数,让父类中的this指向当前子类Person.call(thi......
  • C++ 多态
     多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。https://www.lekaowang.com/zhxfgcs/kfx/0j0/......