Python 面向对象三大特征 -继承

面向对象 - 继承

什么是继承?

继承是面向对象的特征之一,编程语言中的固定语法,用于将一个类继承到另一个类,实现类中代码的复用

出现继承之后,两个类直接的关系如下:

  • 父类: 被继承的类,父类中的代码会被重复利用
    • 也叫 超类(超级类型) 、 基类(基础类型) 、 代码中通过 super 表示
  • 子类: 当前类型,继承父类 可以直接适用父类中的 非私有属性 和 非私有 方法

函数 的出现,实现了代码块的服用
模块 的出现,实现了模块内部代码的复用
继承 的出现,实现了类的复用

代码实现继承

1. 继承是怎么体现的?

- 类
    男人 - 类 

    男人 继承 人  ->  男人 是 人  ->  男人 is

2. 代码实现继承

class 父类:
    def __init__(self):
        父类中的属性
    
    def 父类中的方法(self):
        pass

class 子类(继承的父类名称):
    pass

==============================

class Person:
    def __init__(self, name):
        self.name = name

class Man(Person):
    """子类:男人类型 继承了Person"""
    pass

一个类继承其它类,要将继承的类名称填写在类声明后边的括号中,如果一个类后边不写括号,默认继承 object 类型。 Python中所有的类都是直接或者间接继承自 object

继承的好处?

继承的好处,不仅仅在与重复利用了父类中的非私有属性和方法,同时可以在当前自己的类中完成功能的扩展,提供高能的扩展性。

  • 重复使用父类中(非私有)的属性和方法
  • 子类中扩展新的功能
class Person:
    """定义一个人 类"""
    def __init__(self, name, age):
        """定义一个初始化方法"""
        self.name = name
        self.age = age

    def eat(self):
        """定义一个吃饭的方法"""
        print(f"{self.name}在吃饭...")


class Teacher(Person):
    """定义一个老师的类 继承自 Person"""
    def tech(self):
        """子类中定义一个 教书的方法"""
        print(f"{self.name}在教书...")


damu = Teacher("damu", 18)

damu.eat()  # 子类继承父类的功能
# damu在吃饭...
damu.tech() # 子类对父类功能的扩展
# damu在教书...

适用场景

1.什么时候适用继承

项目中出现了多个相似的类型(管理员,会员,用户等),对应的数据中出现了相同的代码(属性,方法),此时就需要考虑是否通过继承,完成代码的复用性提升!

2.继承关系中,继承什么数据?

Python中的类包含 :

  • 公共的属性和方法
  • 受保护的属性和方法 [属性或者方法前有一个 _ 标识]
  • 私有的属性和方法

继承关系中,子类会继承父类中公共的属性和方法,受保护的属性和方法可以继承但是 IDE工具中会有警告提示,私有的属性和方法理论上不能继承!

方法重写

子类中编写和父类相同的代码

  • 属性相同:就是软件设计上的问题
    需要重构,父类中的属性,子类可以继承过来,不需要在重新编写

  • 方法相同:是继承中的一个功能扩展特性 [方法重写]

    • 子类中重新声明编写父类中已有的方法,完成功能的扩展
    • 代码运行过程中,如果子类中重写了父类中的方法,只会执行子类中的方法

方法重写的好处

  • 子类可以根据自己的特殊情况,重新定义父类中声明的方法,调用时就会执行子类中重写的方法,完成功能的改造
  • 子类可以重写父类的方法,在方法中主动调用父类的方法,达到功能扩展的目的
class Gun:
    """定义一个枪械类"""
    def __init__(self, name):
        self.name = name

    def fire(self):
        """定义一个开火的方法"""
        print(f"{self.name}开火了...")


class Ak47(Gun):
    """定义一个ak47类 继承自 Gun"""

    def fire(self):
        """重写父类中开火的方法"""
        print(f"{self.name}哒哒哒地开火了...")


class M4A1(Gun):
    """定义一个M4a1类 继承自 Gun"""

    def fire(self):
        """重写父类中开火的方法"""
        # 在父类 fire()方法的基础上增添新功能
        print("安装上8倍镜..")
        print("安装上消音器..")
        # 调用父类中的 fire() 方法
        super().fire()
        print("一枪制敌!")

m4 = M4A1("M4A1")
ak = Ak47("AK47")

ak.fire()
# AK47哒哒哒地开火了...

m4.fire()
# 安装上8倍镜..
# 安装上消音器..
# M4A1开火了...
# 一枪制敌!

访问父类方法

调用父类中不同的方法:

  • __特殊方法__()

    • super().__特殊方法__() 调用父类中的方法
  • __私有方法()

    • 子类无法调用
  • 普通方法()

    • super().普通方法() 调用父类中的方法

为什么要调用父类方法

子类通过方法重写,重写了父类中的方法,此时父类的方法就不会执行了
如果子类的方法中需要适用父类方法的功能,就可以通过上述方式主动调用父类中的方法

多继承

代码实现 - 多继承

# 通过在类声明的后边,添加连续的多个父类,完成多继承模式
class Person(Son, Husband, Dad, Employee, Teacher):
    """人的类型:同时继承多个类型"""
    pass

判断对象输入某个类

damu = Person()
isinstance(damu, Person)
# True

多继承中的问题

如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪一个父类中的方法呢?

Python中针对 提供了一个内置属性 mro 可以查看方法的搜索顺序

print(.__mro__)
# (<class '__main__.Son'>, <class '__main__.Dad'>, <class '__main__.Mom'>, <class 'object'>)
  • 在搜索方法时,是按照 __mro__ 的输出结果 从左至右 的顺序查找的
  • 如果在当前类中找到方法,就直接执行,不再搜索
  • 如果没有找到,就查找下一个类中是否有对应的方法,如果找到,就直接执行,不再搜索
  • 如果找到最后一个类,还没有找到方法,程序报错
发布了44 篇原创文章 · 获赞 5 · 访问量 2394

猜你喜欢

转载自blog.csdn.net/qq_36078992/article/details/105568319
今日推荐