• 【python基础】python的继承与多态,子类中调用父类方法和属性


    一. 继承

    在python,所有的类都默认继承object类,因此object类也被称为基类,其他的类称为派生类,在python中继承就是 子类可以继承父类中的所有的 非私有方法

    1. 什么是私有方法?

    指在 Python 的面向对象开发过程中,对象的某些方法(函数)只想在对象的内部被使用,但不想在外部被访问到这些方法或函数。

    即:私有方法是对象不愿意公开的方法或函数。 私有属性同理

    代码示例

    # 1. 公共类 / 父类
    class   Person():
        # 定义__init__初始化方法
        def __init__(self, name, age, adress):
            self.name = name
            self.age = age
            self.adress = adress
    
        def eat(self):
            print('i can eat food!')
    
        def speak(self):
            print('i can speak!')
    
    # 定义个性类
    class Teacher():
        def __init__(self,name,age,adress):
            self.name = name
            self.age = age
            self.adress = adress
    
        def eat(self):
            print('i can eat food!')
    
        def speak(self):
            print('i can speak!')
            
    	def __write(self): # 注意此处 两个下划线 __ 开头 代表私有方法
    		print('i can wirte')
    
    
    # 定义子类 Student  继承person类
    class Student(Person):
        pass
    
    
    p = Person('snail',21,'贵州')
    teacher = Teacher('tom',10,'贵州')
    s1 = Student('xiaowu',87,'四川')
    s1.eat()
    s1.speak()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    继承可以继承父类中的所有非私有方法, 也就是这里的__write方法将不会被继承 __ 是python中私有方法的语法定义 。

    那么执行后你会发现即使Student类中并没有定义eat()方法和speak()方法 但是也同样能够输出 这就是继承。
    继承的语很简单 直接在类后面的括号里面跟上需要继承的类即可。

    2. 重写父类方法

    那么我们想在父类继承来的方法里面执行子类的特有的代码怎么办?
    这里就引入了新的名词重写

    从父类继承过来,只有父类公有的方法和属性,那么我自己想要在父类的基础上面修改方法和属性该怎么办呢?那么重写就是用来解决这个问题的。
    也就是继承后,可以进行修改继承来的方法, 也就是从父类继承来的方法会进行重新定义。

    class Animals(object):
        def eat(self):
            print('i can eat')
    
        def call(self):
            print('i can call phone ')
    
    class Dog(Animals):
        def eat(self):
            print(' i like eat bones!')
    
    
    class Cat(Animals):
        def eat(self):
            print('i like eat mouse!')
    
    
    wang = Dog()
    wang.eat()
    wang.call()
    
    miao = Cat()
    miao.eat()
    miao.call()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3. 在子类中调用父类方法和属性

    c++的子类调用父类方法可以阅读 blog

    既然我们对父类的方法进行重写了,那如果我们还需要调用父类的方法,那该怎么办呢?

    • super().方法名()
    • 类名.方法名(self)
    • spuer(要从哪一个类的上一级类开始查找, self).方法名()

    子类调用父类方法时,一般都是想对父类方法进行扩展。

    当然,super()不光可以调用父类的方法还可以调用父类的属性,完整写法: super().属性 或者super.方法 就可以完成调用了

    代码示例

    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def driver(self):
            print('我是父类person,我喜欢开车')
    
    
    class Father(Person):
        # 如果我们现在想在原有父类方法基础上扩展,例如我们现在需要重写一个init方法
        # 可以接收 name, age ,gender三个属性
        def __init__(self, name, age, gender):
            # 在父类方法中已经添加了name,和age我们可以直接使用
            super().__init__(name, age)
            # 在父类方法的基础上我们在添加一个子类方法独有的功能
            self.gender = gender
    
        def driver(self):
            print('我是子类father,我在开轿车')
    
        def __str__(self):
            return f'我的姓名是{self.name},我的年龄是{self.age},我的性别是{self.gender}'
    
    class Son(Father):
        def driver(self):
            # 调用Person中的dirver
            Person.driver(self) # 注意 父类名直接调用,勿忘加 self,否则会报错!
            
            # 从Father类的上一级类开始查找方法,并进行调用
            super(Father,self).driver()
    
            # 调用Father中的dirver
            super().driver()
            
            # 如果类名是当前类,可以省略括号内的内容,等同于上一句
            super(Son, self).driver() # 格式:super(从哪个类的上一级开始查找,self).方法名()
            
            # 书写特有功能
            print("我是子类son,我在玩遥控车")
    
    
    # 所有的参数都传递到了Father类中,并且添加为当前对象的属性
    print(Father('Jack', 28, '男'))
    print("\n")
    s1 =Son('xiaoming', 12, '男')
    s1.driver()
    
    # 子类中调用父类方法的三种方式:
    # super().方法名()   # 只能调用当前类的上一级类中的方法或函数
    # 类名.方法名(self)  # 所使用的类名,必须在当前类的继承关系中  这种方法可以调用不在类中的类方法,但是不能使用self作为对象出现
    # super(要从哪一个类的上级类开始查询,self).方法名()  # 类名必须在继承关系内,如果类名是当前所在的类,则可以将括号内内容省略,就是第一种方式
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    输出结果如下:
    在这里插入图片描述

    4. 类内部调用自己的成员函数或变量

    上面介绍了子类重写、调用父类的方法,若是 调用自己类内的成员方法或变量呢?

    很简单,直接通过self来调用,见下方代码示例:

    class A:
    	def __init__(self, name):
    		self.name = name
    		
        def a(self):
            print("hello world")
        
        def b(self):
            return self.a()
            print(f"welcome {self.name}!")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上面的self.a()中self是不可缺少的,否则找不到a()的定义,这是和C++/C语言所不同的.

    二. 多态

    多态指的是一类实物有多种形态。

    多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的 相同父类方法,可以产生不同的执行结果;

    不同对象访问相同方法,返回不同结果 就是多态

    1. 多态依赖继承
    2. 子类方法必须要重写父类方法。

    首先定义一个父类,其可能拥有多个子类对象,当我们调用一个公共方法时,传递的对象不同,则返回的结果不同。
    好处,调用灵活,有了多态,可以更容易编写出通用的代码,以适应需求的不断变化。

    代码示例

    class Fruit(object):
        def makejuice(self):
            print('i can make juice ')
    
    
    class Apple(Fruit):
        def makejuice(self):
            print('i can make  apple juice ')
    
    
    class Banana(Fruit):
        def makejuice(self):
            print('i can make Banana juice ')
    
    
    class Orange(Fruit):
        def makejuice(self):
            print('i can make Orange juice ')
    
    
    # 利用多态。  定义一个service  公共方法接口
    def service(obj):
        obj.makejuice()
    
    
    # apple = Apple()
    # apple.makejuice()  # 以往的方式,需要用一个调用一个
    # banana = Banana()
    # banana.makejuice()  # 橘子也是 一样
    # orange = Orange()
    # orange.makejuice()
    
    # 利用接口
    apple = Apple()
    banana = Banana()
    orange = Orange()
    for i in (apple,banana,orange):
        service(i)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    参考链接:
    https://blog.csdn.net/weixin_52599204/article/details/126185049
    https://blog.csdn.net/ljh18885466426/article/details/119492035

  • 相关阅读:
    保姆级python安装教程
    1024程序员节主题征文 | 程序员节节日祝福语大全
    成长杂志成长杂志社成长编辑部2022年第7期目录
    基于Python实现的一款轻量、强大、好用的视频处理软件,可缩视频、转码视频、倒放视频、合并片段、根据字幕裁切片段、自动配字幕等
    Java并发-生产者消费者实现
    前端基础:BFC
    百度相关词易语言查询代码
    人工智能: 一种现代方法 第五章 对抗搜索
    SNP Glue:SAP数据导入到其他系统的多种方式
    英伟达首席科学家:深度学习硬件的过去、现在和未来
  • 原文地址:https://blog.csdn.net/All_In_gzx_cc/article/details/126892543