OOP-继承

继承

  • 子类可以使用弗雷定义的内容或者行为等
  • 继承的实现
    • 父类,基类,超类:被继承的类,Base Class,Super Class
    • 子类:有继承行为的类
    • 所有类都必须有一个父类
    • 如果没有,则默认为object的子类
  • 继承的特征
    • 所有的类都继承自object类,即所有的类都是object类的子类
    • 子类一旦继承父类,则可以使用父类中除私有成员外的所有内容
    • 子类继承父类后并没有将父类成员完全赋值到子类中,而是通过引用关系访问调用
    • 子类中可以定义独有的成员属性和方法
    • 子类中定义的成员合成父类成员如果相同,则优先使用子类成员
    • 子类如果想扩充父类的方法,可以在定义新方法的同时访问父类成员来进行代码重用,可以使用 父类名.父类成员 的格式来调用父类成员,也可以使用super().父类成员的格式来调用
  • 继承变量函数的查找顺序问题
    • 优先查找自己的变量
    • 没有则查找父类
    • 构造函数如果本类中没有定义,则自动查找调用父类构造函数
    • 如果本类有定义,则不再继续向上查找
# 所有类必须有父类
# 默认是object
class Person1():
    pass

class Person2():
    pass
class Person():
    name = "NoName"
    age = 0

# 父类卸载类定义的时候的括号里
class Teacher(Person):
    pass

t = Teacher()
print(t.name)
NoName
class Bird():
    fly = "Yes,we can"
    def flying(self):
        print("飞飞飞")
        return None
    
class BirdMan(Person,Bird):
    pass

bm = BirdMan()
bm.flying()
print(bm.name)
飞飞飞
NoName
# 继承的语法
# 在python中,任何类都有一个共同的父类叫object
class Person():
    name = "NoName"
    age = 0
    __score = 0 # 考试成绩是秘密,只能自己知道
    _petname = "sec" # 小名,是保护的,子类可以用,但不能公用
    def sleep(self):
        print("Sleeping........")
        
# 父类写在括号内
class Teacher(Person):
    teacher_id = "1234"
    def make_test(self):
        print("attention")

t = Teacher()
print(t.name)
print(t._petname)
# 受保护不能外部访问,为啥这里可以
print(Teacher.name)

# 私有访问问题
# 公开访问私有变量,报错
#print(t.score)

t.sleep()
print(t.teacher_id)
t.make_test()
NoName
sec
NoName
Sleeping........
1234
attention
# 子类和父类定义同一个名称变量,则优先使用子类本身
class Person():
    name = "NoName"
    age = 0
    __score = 0 # 考试成绩是秘密,只能自己知道
    _petname = "sec" # 小名,是保护的,子类可以用,但不能公用
    def sleep(self):
        print("Sleeping........")
    
# 父类写在括号内
class Teacher(Person):
    teacher_id = "1234"
    name = "caipo"
    def make_test(self):
        print("attention")
        
t = Teacher()
print(t.name)
caipo

# 子类扩充父类功能的案例
# 人有工作的函数,老师也有工作函数,但老师的工作需要讲课
class Person():
    name = "NoName"
    age = 0
    __score = 0 # 考试成绩是秘密,只能自己知道
    _petname = "sec" # 小名,是保护的,子类可以用,但不能公用
    def sleep(self):
        print("Sleeping........")
    def work(self):
        print("make a money")
    
# 父类写在括号内
class Teacher(Person):
    teacher_id = "1234"
    name = "caipo"
    def make_test(self):
        print("attention")
    
    def work(self):
        # 扩充父类的功能只需要调用父类相应的函数
        #Person.work(self)
        # 扩充父类的另一种方法
        # super代表得到父类
        super().work()
        self.make_test()
        
t = Teacher()
t.work()

make a money
attention

issubclass检测是否是子类

  • 可以用来检测两个类的父子关系
# 利用刚才定义的Bird,BirMan,Person,Teacher,检测父子关系

print(issubclass(BirdMan,Bird))
print(issubclass(BirdMan,Person))
print(issubclass(BirdMan,Teacher))

True
True
False

help(issubclass)

Help on built-in function issubclass in module builtins:

issubclass(cls, class_or_tuple, /)
    Return whether 'cls' is a derived from another class or is the same class.
    
    A tuple, as in ``issubclass(x, (A, B, ...))``, may be given as the target to
    check against. This is equivalent to ``issubclass(x, A) or issubclass(x, B)
    or ...`` etc.

构造函数

  • 在函数实例化的时候调用的一个函数

  • 自动调用

  • 要求,第一个参数必须有,一般推荐self

  • 构造函数的调用时间:一般认为在实例化的时候第一个被调用

  • 一般不手动调用,实例化的时候自动调用,参数需写入类名称后面的括号中

  • 是一类特殊的函数,在类进行实例化之前进行调用

  • 如果子类定义了构造函数,则实例化时使用构造函数,不查找父类构造函数

  • 如果子类没有定义构造函数,则自动查找父类构造函数

  • 如果子类没定义构造函数,父类的构造函数带参数,则构造对象时参数应该安父类参数构造

class Bird():
    def __init__(self):
        print("我被调用了")
        return None
    
# 此时被调用构造函数
b = Bird()

我被调用了

# 构造函数2
class Person():
    def __init__(self,name,age):
        print(name,age)
        
p = Person("wcp",16)

wcp 16

构造函数的继承

  • 构造函数默认继承
  • 一旦子类定义了构造函数,则不再调用父类构造函数
# 构造函数默认继承

class Person():
    def __init__(self,name,age):
        print("Person=({},{})".format(name,age))
        
class Teacher(Person):
    pass

t = Teacher("wcp",16)
t = Teacher()

Person=(wcp,16)

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-6-3e1b46e8ead1> in <module>
      9 
     10 t = Teacher("wcp",16)
---> 11 t = Teacher()

TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'

# 继承中的构造函数

class Animal():
    pass

class Reptile(Animal):
    def __init__(self):
        print("I am Reptile")

class Dog(Reptile):
    # __init__就是构造函数
    # 每次实例化的时候,第一个被调用
    # 因为主要工作是进行初始化,所以得名
    def __init__(self):
        print("I am init in dog")

# 实例化的时候,自动调用了Dog的构造函数
# 因为找到了构造函数,则不再查找父类的构造函数
summer = Dog()
    
# 猫没有写构造函数
class Cat(Reptile):
    pass

# 此时应该自动调用构造函数,因为Cat没有构造函数,所以查找父类构造函数
# 在Reptile中查找到了构造函数,则停止向上查找
c = Cat()

I am init in dog
I am Reptile

# 继承中的构造函数 - 3

class Animal():
    pass

class Reptile(Animal):
    def __init__(self,name):
        print("I am Reptile {0}".format(name))

class Dog(Reptile):
    # __init__就是构造函数
    # 每次实例化的时候,第一个被调用
    # 因为主要工作是进行初始化,所以得名
    def __init__(self):
        print("I am init in dog")

# 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错
summer = Dog()
    
# 猫没有写构造函数
class Cat(Reptile):
    pass

# 此时,由于Cat没有构造函数,则向上查找
# 因为Reptile的构造函数需要两个参数,实例化的时候给了一个,报错
c = Cat()

I am init in dog

---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-13-abcaecb3fe31> in <module>
     24 # 此时,由于Cat没有构造函数,则向上查找
     25 # 因为Reptile的构造函数需要两个参数,实例化的时候给了一个,报错
---> 26 c = Cat()

TypeError: __init__() missing 1 required positional argument: 'name'

# 继承中的构造函数 - 4

class Animal():
    def __init__(self):
        print("Animal")

class Reptile(Animal):
    pass

class Dog(Reptile):
        pass

# 实例化Dog时,查找到Dog的构造函数,参数匹配,不报错
summer = Dog()
    
# 猫没有写构造函数
class Cat(Reptile):
    pass

# 此时,由于Cat没有构造函数,则向上查找
# 因为Reptile的构造函数需要两个参数,实例化的时候给了一个,报错
c = Cat()

Animal
Animal

  • super
    • super不是关键字,而是一个类
    • super的作用是获取MRO(MethodResolustionOrder,方法解析顺序)列表中的第一个类
    • super于父类直接没有任何实质性关系,但通过super可以调用到父类
    • super使用两个方法,参见在构造函数中调用父类的构造函数
print(type(super))
help(super)

<class 'type'>
Help on class super in module builtins:

class super(object)
 |  super() -> same as super(__class__, <first argument>)
 |  super(type) -> unbound super object
 |  super(type, obj) -> bound super object; requires isinstance(obj, type)
 |  super(type, type2) -> bound super object; requires issubclass(type2, type)
 |  Typical use to call a cooperative superclass method:
 |  class C(B):
 |      def meth(self, arg):
 |          super().meth(arg)
 |  This works for class methods too:
 |  class C(B):
 |      @classmethod
 |      def cmeth(cls, arg):
 |          super().cmeth(arg)
 |  
 |  Methods defined here:
 |  
 |  __get__(self, instance, owner, /)
 |      Return an attribute of instance, which is of type owner.
 |  
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |  
 |  __init__(self, /, *args, **kwargs)
 |      Initialize self.  See help(type(self)) for accurate signature.
 |  
 |  __repr__(self, /)
 |      Return repr(self).
 |  
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |  
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  __self__
 |      the instance invoking super(); may be None
 |  
 |  __self_class__
 |      the type of the instance invoking super(); may be None
 |  
 |  __thisclass__
 |      the class invoking super()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值