首页 > 其他分享 >Day09 - 子类父类多继承多层继承多态

Day09 - 子类父类多继承多层继承多态

时间:2023-01-23 18:44:45浏览次数:36  
标签:__ 继承 子类 self 多态 init print class def

1. 子类中访问父类中的私有属性和私有方法

如果想使用父类中的私有属性和私有方法,那么就需要在父类中,为这些私有的属性和方法,提供相应的公有的接口方法来间接访问

2. 如何为父类中的属性进行初始化

在子类中如果定义了自己的初始化方法,那么这时父类的初始化方法就不会再执行了
那么就导致父类中定义的属性无法初始化,子类对象就无法使用继承自父类的属性
如果想正常初始化,需要在子类的初始化方法中,手动调用父类的初始化方法
现阶段调用格式:
父类名.__init__(self,父类中需要属性参数列表)
'''
子类初始化父类的属性
'''

# 父类
class Father(object):
    def __init__(self,name):
        print('Father Init Run ...')
        self.name = name


# 子类
class Son(Father):
    def __init__(self,name, age):
        # 因为子类提供了 init 方法后,那么在使用子类实例对象时,就会调用 子类自己 init 方法,
        # 那么就不会再调用 父类的init方法了,父类当中的属性就不会有绑定的机会,所以这时是没有父类的属性的
        # 如果想父类中的属性可以得到,需要执行父类中的init方法
        # 父类名.init()
        Father.__init__(self, name)
        print('Son Init run ..')
        self.age = age



# 测试
s = Son('Tom', 12)
print(s.name)
print('age:', s.age)

3. 子类中重写和调用父类的方法

在子类继承父类时,子类会拥有父类中的方法.
但是子类并不需要或不满足父类方法中提供的功能,这时就需进行对父类方法重写

重写之后,调用该方法时,执行谁?
答案: 调用重写后子类中的方法
'''
子类重写父类中的方法
'''


# 父类
class Father(object):
    # 实现一个治病
    def cure(self):
        print('父类是个老中医,使用中医古法治病')


# f = Father()
# f.cure()

# 子类
class Son(Father):
    # 子类也是一个大夫,也有治病的功能
    def cure(self):
        # 直接使用 父类名.方法名 形式来引用父类的功能
        Father.cure(self)
        print('子类出国深造,学成以后,使用中西医结合方法治病')


s = Son()
s.cure()

4. 子类方法中调用父类的同名方法

子类调用父类同名方法,第一种方法是:指名道姓,重新在子类中将每个父类方法调用一遍,这种方法代码冗余,但是有多继承的话,也能解决问题;第二种方法是:使用super代替父类的名字调用父类,因此要调用爷爷类的同名方法,那就要在父类中同样使用super代替,所以说super方法比较适合单一继承。

#  super无参数写法
super().__init__()
super().要调用的函数()

5. 多层继承

继承关系有多层,祖孙三代

查找方法:

父类名.方法名(self)
'''
多层继承
'''


class A(object):
    def a(self):
        print('a function')


class B(A):
    def b(self):
        print('b function')


class C(B):
    # C类中重写了B类中的方法
    def b(self):
        B.b(self)
        print('b in C function')

    def c(self):
        print('c function')


class D(C):
    def d(self):
        print('d function')


# 测试
d = D()
d.a()
d.b()
d.c()
d.d()
'''
多层继承
'''


class A(object):
    def __init__(self, a):
        self.a = a


class B(A):
    def __init__(self, a, b):
        A.__init__(self, a)
        self.b = b


class C(B):
    def __init__(self, a, b, c):
        B.__init__(self, a, b)
        self.c = c


class D(C):
    def __init__(self, a, b, c, d):
        C.__init__(self, a, b, c)
        self.d = d


# 测试
d = D(1, 2, 3, 4)
print(d.a)
print(d.b)
print(d.c)
print(d.d)

d.__dict__#保存信息到字典
D.__dict__

6. 多继承

格式:
class 类名(父类名1,.....):
	pass
'''
多层继承:纵向
多继承: 横向

'''


# 定义一个父亲类
class Father(object):
    def func_fa(self):
        print('Father Function ...')


# 定义一个母亲类
class Mother(object):
    def func_mo(self):
        print('Mother function ...')


# 上面的两个类,有一个共同子类
class Son(Father, Mother):
    def play(self):
        print('Son play...')


# 测试
s = Son()
s.play()
s.func_fa()
s.func_mo()

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

7. 多继承的初始化

'''
多继承的初始化问题
'''


# 定义一个人类
# 在这种 继承关系 上,这个共同的父类 Person 会被初台化多次,这是继承时的问题
# 是否 父类名调用 实始化方法的时候 引起的
class Person(object):
    def __init__(self, aaa):
        print('Person Init ...')
        self.aaa = aaa


class Father(Person):
    def __init__(self, aaa, name):
        Person.__init__(self, aaa)
        print('Father Init ...')
        self.name = name


class Mother(Person):
    def __init__(self, aaa, age):
        Person.__init__(self, aaa)
        print('Mother Init ...')
        self.age = age


class Son(Father, Mother):
    def __init__(self, aaa, name, age, gender):
        Father.__init__(self, aaa, name)
        Mother.__init__(self, aaa, age)
        print('Son Init ...')
        self.gender = gender


# 测试
s = Son(1, 'Tom', 12, '男')
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)

'''
多继承的初始化问题的解决
'''


# 定义一个人类

class Person(object):
    def __init__(self, aaa):
        print('Person Init ...')
        self.aaa = aaa


class Father(Person):
    def __init__(self, aaa, name, age):
        super(Father, self).__init__(aaa, age)
        print('Father Init ...')
        self.name = name


class Mother(Person):
    def __init__(self, aaa, age):
        super(Mother, self).__init__(aaa)
        print('Mother Init ...')
        self.age = age


class Son(Father, Mother):
    def __init__(self, aaa, name, age, gender):
        # 参数二是当前类的实例对象
        # 参数一是当前类名
        # 在参数二对象的所属类的mro关系 中找参数一的下一个类进行实始化
        super(Son, self).__init__(aaa, name, age)
        print('Son Init ...')
        self.gender = gender


# 测试
s = Son(1, 'Tom', 12, '男')
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)

print(Son.__mro__)
'''
这个顺序关系是解释器在执行代码 时,自动确认的我们无法干涉
(<class '__main__.Son'>,
 <class '__main__.Father'>, 
 <class '__main__.Mother'>, 
 <class '__main__.Person'>, 
 <class 'object'>)
'''

# f = Father('tom',1)
print(Father.__mro__)

父类名调用  理解
super()调用  使用
super(类名,self) 了解 
'''
多继承的初始化问题的解决
'''


# 定义一个人类

class Person(object):
    def __init__(self, aaa):
        print('Person Init ...')
        self.aaa = aaa


class Father(Person):
    def __init__(self, name, *args):
        # super(Father, self).__init__(*args)
        super().__init__(*args)
        print('Father Init ...')
        self.name = name


class Mother(Person):
    def __init__(self, age, *args):
        # super(Mother, self).__init__(*args)
        super().__init__(*args)
        print('Mother Init ...')
        self.age = age


class Son(Father, Mother):
    def __init__(self, gender, name, age, aaa):
        # 参数二是当前类的实例对象
        # 参数一是当前类名
        # 在参数二对象的所属类的mro关系 中找参数一的下一个类进行实始化
        # super(Son, self).__init__(name,age,aaa)
        super().__init__(name, age, aaa)
        print('Son Init ...')
        self.gender = gender


# 测试
# s = Son(1, 'Tom',12,'男')
s = Son('男', 'Tom', 12, 1)
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)

print(Son.__mro__)
'''
这个顺序关系是解释器在执行代码 时,自动确认的我们无法干涉
(<class '__main__.Son'>,
 <class '__main__.Father'>, 
 <class '__main__.Mother'>, 
 <class '__main__.Person'>, 
 <class 'object'>)
'''

f = Father('Jack', 2)
print(f.aaa)
print(f.name)
print(Father.__mro__)
super执行过程:
在 self 这个对象的所属类中,通过 __mro__ 找到方法解析顺序
在顺序中,找当前类名的下一个类来初始化或查找方法
'''
类的继承书写顺序会影响mro顺序
'''


class A(object):
    pass


class B(A):
    pass


class C(A):
    pass


# class D(B,C):
# (<class '__main__.D'>, < class '__main__.B' >, < class '__main__.C' >, < class '__main__.A' >, < class 'object' > )

class D(C, B):
    # (<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
    pass


print(D.__mro__)

在多继承时,如果继承的多个类同时继承同一个父类,那么这时会出现初始化问题
这个共同父类会被初始化多次.

类名.__mro__ 得到了一个元组,元组中的元素是当前类在继承关系上的一个顺序

方法解析顺序
method relational ordered

这个顺序不是我们确定的,是由在确定某个类的继承关系关系后,由解释器来确定这个顺序
'''
多重多继承时,方法的查找顺序也参考MRO
'''


class A(object):
    def show(self):
        print('A _ Show Run ...')

    def info(self):
        print('A - Info run ...')


class B(A):
    def show(self):
        print('B _ Show Run ...')


class C(A):
    def show(self):
        print('C _ Show Run ...')

    def info(self):
        # super().info()
        # A.info(self)
        print('C - Info run ...')


class D(B, C):
    def show(self):
        super().show()
        A.show(self)
        print('D _ Show Run ...')


d = D()
d.show()
d.info()

super对象是基于类的mro顺序来对当前类进行初始化的
基于这个mro顺序可以保证,所有的继承关系的上类,都只执行一次
'''
多继承的初始化问题的解决
'''


# 定义一个人类

class Person(object):
    def __init__(self, aaa):
        print('Person Init ...')
        self.aaa = aaa


class Father(Person):
    def __init__(self, name, *args):
        super(Father, self).__init__(*args)
        print('Father Init ...')
        self.name = name


class Mother(Person):
    def __init__(self, age, *args):
        super(Mother, self).__init__(*args)
        print('Mother Init ...')
        self.age = age


class Son(Father, Mother):
    def __init__(self, gender, name, age, aaa):
        # 参数二是当前类的实例对象
        # 参数一是当前类名
        # 在参数二对象的所属类的mro关系 中找参数一的下一个类进行实始化
        super(Son, self).__init__(name, age, aaa)
        print('Son Init ...')
        self.gender = gender


# 测试
# s = Son(1, 'Tom',12,'男')
s = Son('男', 'Tom', 12, 1)
print(s.aaa)
print(s.name)
print(s.age)
print(s.gender)

print(Son.__mro__)
'''
这个顺序关系是解释器在执行代码 时,自动确认的我们无法干涉
(<class '__main__.Son'>,
 <class '__main__.Father'>, 
 <class '__main__.Mother'>, 
 <class '__main__.Person'>, 
 <class 'object'>)
'''

f = Father('Jack', 2)
print(f.aaa)
print(f.name)
print(Father.__mro__)
mro -> 一个类的继承书写顺序会影响mro顺序

8. 多继承调用指定父类中方法

	父类名.方法()
	super().方法()

9. 多态

多种形态
程序中的意义:
	当调用一个方法名的时候,得到的结果不同
	在一般的面向对象语言中,多态是由继承来实现的
	但是在python中,python,天生具有多态性


鸭子类型: Duck Typing
	一只鸟如果长的鸭子,叫声像鸭子,那么就认为它就是鸭子
'''
多态
'''


# 标准多态

class Father(object):
    def cure(self):
        print('老中医使用中医治病')


class Son(Father):
    def cure(self):
        print('小大夫使用中西医结合治病')


class Dog(object):
    def bark(self):
        print('Won won ...')


class AnimalDoctor(object):
    def cure(self):
        print('我是个兽医,主要给动物治病,但是也能给人凑合治一下')


# 病人类
class Person(object):
    # 需要一个大夫给他治病
    def need_doctor(self, doctor):
        doctor.cure()


# 测试
p = Person()

p.need_doctor(Father())
p.need_doctor(Son())
# p.need_doctor(Dog())
p.need_doctor(AnimalDoctor())

10. 实例对象属性和实例对象方法

以 对象名.xxx  的形式调用的都是实例的属性或实例的方法
'''
实例属性和实例 方法
'''


class Cat(object):
    def __init__(self, name):
        # 定义一个实例 属性
        self.name = name

    # 定义了一个实例方法
    def info(self):
        print(self.name)

    def show(self):
        print('Show Run :')
        self.info()


# 测试
tom = Cat('Tom')
# 使用实例属性
print(tom.name)
# 使用实例方法
tom.info()
tom.show()

# Python中万物皆对象
# print(Cat.name)
Cat.show()

# 结论:
# 为什么类名不能调用 实例 对象属性和实例对象方法呢?
# 因为类对象存在时,不一定有实例对象存在
# 实例属性和实例 方法只能由实例对象调用

​ 实例属性和实例方法只能由实例对象调用

11. 类对象和类属性

类属性可以使用实例对象来引用,但是不能修改
一般情况下:类属性 都只使用 类对象 来调用

类对象.类属性
'''
类对象和类属性
'''


class ClassRoom(object):
    # 当定义一个类属性时,相当于这个类中的全局变量
    # 该类的所有对象都 可以使用该 类属性
    # 可以在所有的对象间进行数据共享
    center_kong_tiao = '格力空调'

    # 实例方法
    def show(self):
        print('实例方法中去访问类属性:')
        print(ClassRoom.center_kong_tiao)


cr901 = ClassRoom()
print(cr901.center_kong_tiao)

cr902 = ClassRoom()
print(cr902.center_kong_tiao)

cr903 = ClassRoom()
print(cr903.center_kong_tiao)

# cr901.center_kong_tiao = '海尔空调'
ClassRoom.center_kong_tiao = '海尔空调'
print(cr901.center_kong_tiao)
print(cr902.center_kong_tiao)
print(cr903.center_kong_tiao)

cr901.show()

扩展

'''
扩展:属性和方法的保存位置
'''

class Cat(object):
    def __init__(self,name):
        self.name = name
        self.__age = 1

    def public_method(self):
        print('公有的对象方法')

    def __private_method(self):
        print('私有的对象方法')


tom = Cat('Tom')
jack = Cat('Jack')
# __dict__ 是一个魔法属性,用来保存当前对象的所有的成员
print(Cat.__dict__)
print(tom.__dict__)
print(jack.__dict__)

tom.public_method()

Cat.public_method(tom)
Cat.public_method(jack)

def display():
    print('Display')

display()

标签:__,继承,子类,self,多态,init,print,class,def
From: https://www.cnblogs.com/lehoso/p/17065368.html

相关文章

  • Day08 - 面向对象和继承
    1.面向对象烤地瓜分析'''烤地瓜安全'''#抽象一个地瓜类#实现初始化方法,初始地瓜的状态和总烧烤时间#添加一个用来保存调料的容器属性#实现一个烧烤方法 ......
  • mt_Day7: 多态、内部类、一些常用API
    多态同类型对象,执行同一个行为,会表现出不同的特征多态成员访问特点:方法调用:编译看左边,运行看右边变量调用:编译看左边,运行也看左边(多态侧重行为多态)publicabstrac......
  • mt_Day5:static与继承
    static静态关键字1.static成员变量static+成员变量:该变量在内存中只存储一份,可以被共享访问、修改。静态成员变量的访问publicclassUser{/***例子:......
  • java 多态学习笔记
    因为在想去一个家乡的小国企,每个月五六千块钱或许也不错,所以懈怠了学习。但是论语中有说:取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣。如果我想着只是进一个小地......
  • java 继承 补充:子类能继承父类中的哪些内容?
    目录继承内存图构造方法的继承成员变量的继承成员方法的继承继承的特点成员变量的访问特点成员方法的访问特点方法的重写构造方法的访问特点继承内存图父类中有:成员变量......
  • 【并发编程】原子类
    文章目录​​1.什么是原子类​​​​2.原子更新基本类型​​​​3.原子更新数组类型​​​​4.原子地更新属性​​1.什么是原子类(1)原子类简介一度认为原子是不可分割的最小......
  • 【Django drf】 序列化类常用字段类和字段参数 定制序列化字段的两种方式 关系表外键
    目录序列化类常用字段类和字段参数常用字段类常用字段参数选项参数通用参数序列化类高级用法之sourcesource填写类中字段source填写模型类中方法source支持跨表查询定制序......
  • 【转载】 python鸭子类型与protocol
    版权声明:本文为CSDN博主「yuanzhoulvpi」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/yuanzhoulvpi/article/deta......
  • c++入门篇之C++ 多态
    多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。C++多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数......
  • 【Javaweb】Servlet三|实现Servlet程序的几种方法及Servlet继承体系说明
    GET和POST请求的分发处理代码如下注意页面要和index位置一样否则浏览器找不到注意大小写HttpServletRequesthttpServletRequest=(HttpServletRequest)servletReq......