python面向对象2-类的继承

python面向对象2-类的继承

实践出真知,去自己实践代码吧

类的继承基本语法:

class 派生类名(基类名):

                  ...

面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。

第一部分

如果在子类中需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法。
**

举例1

**(不重写父类的构造方法):


```python
class Father(object):
    def __init__(self, name):
        self.name = name
        print("name: %s" % (self.name))

    def getName(self):
        return 'Father ' + self.name

class Son(Father): # 子类不重写 __init__,实例化子类时,会自动调用父类定义的 __init__。
    def getName(self):
        return 'Son ' + self.name

if __name__ == '__main__':
    son = Son('runoob')
    print(son.getName())
结果: name: runoob
     Son runoob

**

举例2

**(重写父类的构造方法):

class Father(object):
    def __init__(self, name):
        self.name = name
        print("name: %s" % (self.name))

    def getName(self):
        return 'Father ' + self.name

class Son(Father):
    def __init__(self, name):
        print("hi")
        self.name = name

    def getName(self):
        return 'Son ' + self.name

if __name__ == '__main__':
    son = Son('runoob')
    print(son.getName())
结果:hi
    Son runoob

**

举例3

**(重写父类的构造方法):
如果重写了__init__ 时,要继承父类的构造方法,可以使用 super 关键字:

 语法:  super(子类,self).__init__(参数1,参数2,....)
 或者     super().__init__(参数1,参数2,....)
class Father(object):
    def __init__(self, name):
        self.name = name
        print("name: %s" % (self.name))

    def getName(self):
        return 'Father ' + self.name

class Son(Father):
    def __init__(self, name):
        super(Son, self).__init__(name)
        print("hi")
        self.name = name

    def getName(self):
        return 'Son ' + self.name

if __name__ == '__main__':
    son = Son('runoob')
    print(son.getName())
结果: name: runoob
     hi
     Son runoob

第二部分(这部分是一些基本概念,实践操作理解看第三部分)

(1)在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
(2)Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
(3)在类的继承中,私有属性,类变量并没有什么特殊,都可以在子类中使用,但私有方法不能直接调用,可以被重写。
(4)查看继承的特殊属性和方法

__base__ : 类的基类
__based__ : 类的基类元组
__mro__ : 显示方法查找顺序,基类的元组
__subclasses__() : 类的子类列表

(5)继承中的访问控制

  • 私有的都是不可以访问的,但是本质上依然是改了名称放在这个属性所在类的__dict__中

  • 继承时,公有的,子类和实例都可以随意访问,私有成员被隐藏了,子类和实例不可直接访问

  • 当私有变量所在的类内的方法中可以访问这个私有变量

第三部分(针对单继承)
子类中调用父类的方法:
1:类名.方法名(self,参数)
2:super(子类名,self).方法名(参数)
3:super().方法名(参数)
注:在下面的代码中我发现可以直接在子类中通过self.方法名(参数)调用父类中没有被重写的的方法,若是方法已经被子类重写,则调用的是被重写后的方法。

创建Animals(动物)基类:

class Animals(object):
    eye='褐色' # 类变量

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

        self.set_age(age) # 定义私有属性
        print("调用父类的构造方法")

    def set_age(self,age):
        self.__age=age

    def get_age(self):
        return self.__age

    def channel(self):
        print("调用父类的公共方法channel()")

    def choice(self):
        print("调用父类的公共方法choice()")

    def sd(self):
        print("sssssssss")

    def __performance(self):
        print("调用父类的私有方法")

    pass

创建Cat(猫)子类:

class Cat(Animals):
    def __init__(self,name,color,age,food):
        super().__init__(name,color,age)
        self.food=food

    # def channel(self):
    #     super().channel() 

    def choice(self):
        print("重写父类的公共方法choice()")
        Animals.sd(self) # 类名.方法名(self,参数)
        self.channel() # self.被重写后的父类的方法名(参数)
        

    def channel(self):
        print("重写父类的公共方法channel()")
        print(f"{self.name}的年龄是:{self.get_age()},食物是{self.food}")


    def __performance(self):
        print("在类的继承中,私有属性,类变量并没有什么特殊,都可以在子类中使用,但私有方法不能直接调用,可以被重写")
        Animals.eye='水晶色'
        print(f"{self.name}的眼睛是{Animals.eye}的")

    def jiekou(self): # (创建接口方法间接使用私有方法)
        self.__performance()

    pass
cat=Cat('波斯猫','白色',5,'雪山旗鱼')
print(dir(cat))
cat.choice()
cat.channel()
cat.jiekou()
print(cat.get_age())

第四部分 (针对多级继承,代码继承上面的类)
创建Dog(狗)子类:(注意:狗类继承的是猫类)

 class Dog(Cat):
    def pao(self):
        print(f"{self.name}追着波斯猫跑")

    def k(self):
        # self.jiekou()
        super(Dog,self).jiekou()

    pass    
dog=Dog('旺财','黄色',4,'大骨头')
print(dog.__dict__)
print(dir(dog))
dog.k()
print(Dog.__mro__) # 该方法可以列出类的继承顺序链

第四部分 (针对多继承,感觉和上面的多级继承差不多)
*************(以下代码与上面代码无关)

创建 Animal类(基类)

  class Animal(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def Perform(self):
        print("动物世界真好看")

    pass

创建 Bird类(基类)

class Bird(object):
    def __init__(self,name,age,food):
        self.name=name
        self.age=age
        self.food=food

    def Perform(self):
        print("鸟类能飞")

    pass

创建Eagle类(子类,同时继承上面的两个类)

class Eagle(Bird,Animal):
    pass
eagle=Eagle('老鹰',10) # 系统报错:TypeError: __init__() missing 1 required positional argument: 'food'
eagle=Eagle('老鹰',10,'肉') # 系统不报错 说明Eagle类默认继承了Bird类的构造方法,参数要与Bird类的参数保持一致
print(eagle.__dict__) # {'name': '老鹰', 'age': 10, 'food': '肉'}
class Eagle(Animal,Bird):
    pass
eagle=Eagle('老鹰',10) # 系统不报错,说明说明Eagle类默认继承了Animal类的构造方法,参数要与Animal类的参数保持一致
print(eagle.__dict__) # {'name': '老鹰', 'age': 10}

由此我们可以得出:多继承下的子类按照继承的顺序依次查找所需要的属性或方法。

通过下面的代码再加深理解:(继承的类先后顺序不同)

——class Eagle(Animal,Bird)

class Eagle(Animal,Bird):
     pass
# 
 eagle=Eagle('老鹰',10)
 eagle.Perform()
 print(Eagle.__mro__) # 列出继承顺序链,依次查找
 # (<class '__main__.Eagle'>, <class '__main__.Animal'>, <class '__main__.Bird'>, <class 'object'>)

——class Eagle(Bird,Animal)

class Eagle(Bird,Animal):
    pass

eagle=Eagle('老鹰',10,'肉')
eagle.Perform()
print(Eagle.__mro__)
#(<class '__main__.Eagle'>, <class '__main__.Bird'>, <class '__main__.Animal'>, <class 'object'>)

实践出真知,去自己实践代码吧

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白夜的月亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值