cccyyys 发表于 2021-6-28 10:53

【笔记】继承详解2

昨天回来太晚了,也没来的及多看,今天才发现原来继承还没有学习完,今天继续,哈哈哈哈{:301_1005:}
方法的重写
子类可以重新定义父类中的方法,这样就会覆盖父类的方法,称为“重写”。
class Person:
    def __init__(self,name,age):
      self.name = name
      self.__age = age#私有属性
    def say_age(self):
      print('不知道')
    def say_introduce(self):
      print("我的名字是:",self.name)

class Student(Person):
    def __init__(self,name,age,score):
      Person.__init__(self,name,age)
      '''self.name = name
      self.age = age'''
      self.score = score
    def say_age(self):
      '''对say_age进行重写'''
      print("老师,我的年龄是:{0}".format(self._Person__age))

s = Student('cys',18,100)
print(dir(s))
s.say_age()
s.say_introduce()
运行结果:['_Person__age', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name', 'say_age', 'say_introduce', 'score']
老师,我的年龄是:18
我的名字是: cys
以上是方法重写的实例,方法重写就相当于在子类中重新定义一个重名方法,然后覆盖掉父类的方法,注意,针对私有属性,子类继承的属性名字是_Person__age,所以在调用时需要使用调用私有属性的方法。
查看类的层次结构
通过类的方法mro()或者类的属性__mro__可以输出这个类的继承层次结构。
class A:
    pass
class B(A):
    pass
class C(B):
    pass
print(C.mro())
运行结果为:[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
这个类的层次结构是C继承B,B继承A,A继承根类object类。
object根类
object类是所有类的父类,因此所有的类都有object类的属性和方法。
为了学习object类,我们可以先学习一下内置函数dir(),他可以让我们方便的看到指定对象所有的属性
class Person:
    def __init__(self,name,age):
      self.name = name
      self.age = age

    def say_age(self):
      print("{0}的年龄是:{1}".format((self.name,self.age)))

obj = object()#查看object类所有的属性
print(dir(obj))
s = Person('cys',18)#查看Person中所有的属性
print(dir(s))
运行结果:['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'say_age']
可以看出,Person中包含了object类中所有属性,又新增加了__weakref__、name、age、say_age、__module__、__dict__,其中name、age、say_age就是我们Person类中新定义的属性和方法。
重写srt()方法
object中有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str(),经常用于print()方法,可以对srt()重写,实际上利用的就是继承中方法的重写原理,重写object类的__str__()方法
class Person:
    def __init__(self,name):
      self.name = name

p = Person('cys')
print(p)
运行结果为:<__main__.Person object at 0x0000020CC9C95AC0>
这就是利用object类中__str__()方法返回的对应对象的描述,可以对其进行重写。
class Person:
    def __init__(self,name):
      self.name = name
    def __str__(self):
      '''对str()方法重写'''
      return "我的名字叫{0}".format(self.name)

p = Person('cys')
print(p)
运行结果为:我的名字叫cys
注意,在重写__str__()时,这个方法是需要返回字符串的,如果没有设置返回值,或者返回值类型不是字符串,都会报错。
多重继承
Python支持多重继承,一个子类可以有多个“直接父类”。这样,就具备了“多个父类”的特点。但是由于这样会使“类的整体层次”异常复杂,不便于维护,尽量避免使用。
class a:
    def aa(self):
      print('aa')
class b:
    def bb(self):
      print('bb')
class c(b,a):
    def cc(self):
      print('cc')
s = c()
s.aa()
s.bb()
s.cc()
运行结果:aa
bb
cc
这是一个多重继承,尽量避免使用。
mro()函数
Python支持多继承,如果父类中有相同名字的方法,在子类中没有指定父类名是,解释器将“从左向右”依次检索。
class a:
    def aa(self):
      print('aa')
    def say(self):
      print('say aaaa')
class b:
    def bb(self):
      print('bb')
    def say(self):
      print('say bbbb')
class c(b,a):
    def cc(self):
      print('cc')
s = c()
s.say()
运行结果:say bbbb
super()获得父类定义
在子类中,如果想要获得父类的方法时,可以同过super()来做。super()代表父类的定义(定义可以看做代码),不是父类对象。
class A:
    def say(self):
      print("A:",self)
class B(A):
    def say(self):
      #A.say(self)可以直接通过类名调用
      super().say()#通过super()方法直接获取父类的定义
      print('B:',self)

B().say()
运行结果:A: <__main__.B object at 0x000001C01ABF5A90>
B: <__main__.B object at 0x000001C01ABF5A90>
在B中使用A中的方法,可以通过类名直接调用,也可以使用super()方法获取父类的定义。
好了,继承到这里就正式结束了。欢迎大家批评指正!
页: [1]
查看完整版本: 【笔记】继承详解2