Python面向对象编程:继承与多态

1.继承

概念:
        继承是面向对象编程的核心特性之一,它允许一个类(子类/派生类)继承另一个类(父类/基类)的属性和方法,从而建立类之间的父子关系。通过继承,子类可以复用父类的功能,同时还能扩展或修改父类的行为。

语法:

class 子类名(父类名):
    # 子类的代码块
    pass

关键特性:

单继承

子类仅继承一个父类,形成简单的层级关系。

总结:子类可以继承父类的属性和方法,就算子类自己没有,也可以使用父类的

# 1.继承
# 就是让类和类之间转变为父子关系,子类默认继承父类的属性和方法
# 1.1 语法
# class 类名(父类名):
#   代码块
# 1.2 单继承
class Person:       # 父类
    def eat(self):
        print('吃饭')
    def sing(self):
        print('唱歌')
class Girl(Person):     # Person类的子类
    pass        # 占位符, 代码里面类下面不会写任何东西,会自动跳过,不会报错
class Boy(Person):
    pass
li = Girl()
li.eat()
li.sing()

li2 = Boy()
li2.eat()
li2.sing()
# 总结:子类可以继承父类的属性和方法,就算子类自己没有,也可以使用父类的

多继承

1.子类可以继承多个父类,通过逗号分隔父类名。

2.需注意方法解析顺序(MRO)可能引发的冲突。

3.A/B/C C(子类)继承于B(父类),B类(子类)继承A类(父类),C类具有A/B类的属性和方法

4.子类拥有父类的父类的属性和方法

5.继承的传递性就是子类拥有父类以及父类的父类中的属性和方法

# 1.3 继承的传递(多重继承)
# A/B/C C(子类)继承于B(父类),B类(子类)继承A类(父类),C类具有A/B类的属性和方法
# 子类拥有父类的父类的属性和方法
class Father:
    def eat(self):
        print('吃饭')
    def sleep(self):
        print('睡觉')
class Son(Father):  # Father类的子类
    pass
class Grandson(Son): # Son的子类
    pass
li3 = Son()
li3.eat()
li3.sleep()
li4 = Grandson()
li4.eat()
li4.sleep()
# 继承的传递性就是子类拥有父类以及父类的父类中的属性和方法

示例扩展:

# 多继承的实际应用
class ElectricAppliance:
    def power_on(self):
        print("Powering on...")

class ScreenDevice:
    def display(self):
        print("Displaying content...")

class SmartTV(ElectricAppliance, ScreenDevice):  # 组合功能
    def streaming(self):
        print("Streaming video...")

应用场景:

  • 代码复用:避免重复定义相同功能。
  • 扩展功能:子类可在继承基础上添加新特性。
  • 接口抽象:定义基类规范,子类实现具体逻辑(如抽象类)。

注意事项:

  • 子类会继承父类的所有公共属性和方法(私有成员需通过特殊方式访问)。
  • 若子类重写父类方法,优先调用子类方法(方法覆盖)。
  • 多继承时,可通过类名.__mro__查看方法调用顺序。

2.方法的重写(Method Overriding)

含义:

        在面向对象编程中,当一个子类继承了父类的某个方法,但需要对该方法的具体实现进行修改或扩展时,可以在子类中重新定义该方法。这个过程称为方法的重写,也称为方法的覆盖。

核心要点:

  1. 方法签名必须完全相同(包括方法名、参数列表和返回类型)
  2. 访问权限不能比父类方法更严格
  3. 子类方法可以抛出比父类方法更少的异常,但不能抛出新的或更广泛的异常
  4. 可以使用 @Override 注解来明确标识这是一个重写方法

实际应用场景:

  1. 当子类需要对父类方法实现不同的行为时
  2. 当子类需要扩展父类方法功能时
  3. 当子类需要优化父类方法的性能时

示例(python代码):

# 1.4 重写指在子类中定义于父类相同名称的方法
# 1.4.1 覆盖父类方法
class Person:  # 父类
    def money(self):
        print('一百万')
class Man(Person):  # 子类
    def money(self):
        print('一千万')
li = Man()
li.money()

实现对父类方法进行扩展的三种方式:

  • 1.父类名.方法名(self)
# 1.4.2 对父类方法进行扩展:继承父类的方法,子类也可以增加自己的功能
# 1.父类名.方法名(self)
class Person:  # 父类
    def money(self):
        print('一百万')
class Man(Person):  # 子类
    def money(self):
        Person.money(self)
        print('一千万')
li = Man()
li.money()
  • 2.super().方法名() --推荐使用
# 2.super().方法名()  --推荐使用
# super在python里面是一个特殊的类,super()是使用super类创建出来的对象,可以调用父类中的方法
class Person:  # 父类
    def money(self):
        print('一百万')
    def sleep(self):
        print('睡觉')
class Man(Person):  # 子类
    def money(self):
        super().money()
        super().sleep() # 可以调用父类中的其他方法
        print('一千万')
li = Man()
li.money()
  • 3.super(子类名,self).方法名
# 3.super(子类名,self).方法名
class Person:  # 父类
    def money(self):
        print('一百万')
    def sleep(self):
        print('睡觉')
class Man(Person):  # 子类
    def money(self):
        super(Man,self).money()
        super(Man,self).sleep()
        print('一千万')
li = Man()
li.money()

注意事项:

  1. 静态方法不能被重写,只能被隐藏
  2. 构造方法不能被重写
  3. 私有方法不能被重写
  4. 重写方法可以使用 super 关键字调用父类的原始实现

3.新式类写法详解

        Python中的新式类(New-style classes)是指继承自object的类,这是Python 2.2版本引入的重要改进。与经典类(旧式类)相比,新式类提供了更多功能和更好的性能。

基本语法:

class MyClass(object):
    """这是一个新式类"""
    def __init__(self, value):
        self.value = value
        
    def display(self):
        print(f"Value is: {self.value}")

主要特点:

  1. 必须显式继承object:在Python 2.x中,必须明确继承object类才能成为新式类;在Python 3.x中,所有类默认都是新式类

  2. 方法解析顺序(MRO):使用C3线性化算法,比经典类的深度优先搜索更合理

  3. 支持描述符协议:可以实现property、staticmethod、classmethod等高级特性

  4. 支持super()函数:可以更安全地调用父类方法

实际应用示例:

class Animal(object):
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        raise NotImplementedError("子类必须实现此方法")

class Dog(Animal):
    def speak(self):
        return f"{self.name} says: Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says: Meow!"

新式类优势:

  1. 更好的方法解析:避免经典类在多重继承中的"钻石问题"

  2. 丰富的内置方法:支持__slots____getattribute__等特殊方法

  3. 元类支持:可以更灵活地控制类的创建过程

  4. 性能优化:新式类的属性访问等操作通常更快

与经典类的区别示例:

# 经典类写法(Python 2.x)
class OldClass:
    pass

# 新式类写法(Python 2.x)
class NewClass(object):
    pass

在Python 3.x中,所有类都是新式类,即使不显式继承object。

4.多态:

含义

        多态是指一个对象在不同使用环境中可以表现出多种形态。具体来说,同一个方法调用由于对象的不同可能产生不同的行为,这种特性称为多态性。多态是面向对象编程的三大基本特性之一(封装、继承、多态)。

前提条件

  1. 继承关系:必须存在类之间的继承关系(父类和子类关系)
  2. 方法重写:子类必须对父类的某些方法进行重写(override),即子类提供了父类方法的特定实现

    完整示例

    class Animal:
        def speak(self):
            pass
    
    class Dog(Animal):
        def speak(self):
            return "汪汪"
    
    class Cat(Animal):
        def speak(self):
            return "喵喵"
    
    def animal_speak(animal):
        print(animal.speak())
    
    dog = Dog()
    cat = Cat()
    animal_speak(dog)  # 输出: 汪汪
    animal_speak(cat)  # 输出: 喵喵
    

    注意事项

    • Python是动态语言,多态的实现更加灵活,不需要严格的类型声明

      可以通过抽象基类(ABC)来强制子类实现特定方法

      多态常与鸭子类型(Duck Typing)概念相关联

    主要特点

    行为导向:不关注对象的具体类型,而是关注对象是否具有相同名称的方法。只要对象具有相同的方法签名,就可以被统一调用。

    示例:假设有Animal类和其子类Dog、Cat,都定义了makeSound()方法。调用时不需要知道具体是Dog还是Cat,只要知道它能makeSound即可。

    5.静态方法:

    • 定义格式:
    • class 类名:
      • @staticmethod
      • def 方法名(形参):
        • 方法体
    • 调用格式:
    • 类名.方法名(实参)
    • 对象名.方法名(实参)

    含义:

            静态方法(Static Method)是面向对象编程中一种特殊的方法类型。下面详细介绍其定义和使用方式:

    定义格式详解:

    class 类名:
        @staticmethod  # 使用装饰器声明为静态方法
        def 方法名(形参1, 形参2=默认值):  # 可以包含多个形参,也可以设置默认参数
            """方法的文档字符串,说明方法功能"""
            方法体代码  # 通常包含与类相关但不依赖实例的操作
            return 返回值  # 可选
    

    典型特征:

    1. 不需要传入self参数
    2. 不能访问类属性和实例属性
    3. 相当于一个普通函数,只是逻辑上属于某个类

    调用方式说明:

    1. 通过类名直接调用(推荐方式)
    类名.方法名(实参1, 实参2)  # 例如:MathUtils.calculate_average(85, 90)
    

    1. 通过实例对象调用(不推荐)
    obj = 类名()
    obj.方法名(实参)  # 例如:calculator = Calculator(); calculator.add(5,3)
    

    示例:

    # 5.静态方法
    # 使用@staticmethod来进行修饰,静态方法没有self,cls参数的限制
    # 静态方法与类无关,可以被转换成函数使用
    class Person(object):
        @staticmethod   # 静态方法
        def study(name):
            print(f'{name}会学习')
    # 静态方法既可以使用对象访问,也可以使用类访问
    Person.study('三笠')
    li = Person()
    li.study('三笠')  # 调用方法时传参数
    # 取消不必要的参数传递,有利于减少不必要的内存占用和性能消耗

    注意事项:

    • 静态方法无法修改类状态或实例状态
    • 通常用于组织代码,将相关功能分组到类中
    • 调用时无需创建类实例,节省资源

    6.类方法:

    基本概念:

    类方法(Class Method)是面向对象编程中定义在类上而非实例上的方法。它通过@classmethod装饰器标识,第一个参数通常命名为cls,指向类本身而非实例。

    主要特点:

    1. 访问类级属性:可以访问和修改类变量
    2. 无需实例化:可以直接通过类名调用,不需要创建对象实例
    3. 工厂模式:常用于实现替代构造函数的功能

    语法示例:

    class MyClass:
        class_variable = "类变量"
    
        @classmethod
        def class_method(cls):
            print(f"访问类变量: {cls.class_variable}")
            return cls()  # 可以返回类的新实例
    

    使用场景:

    1. 替代构造函数

    当需要多种创建对象的方式时,可以使用类方法作为工厂方法:

    class Date:
        def __init__(self, year, month, day):
            self.year = year
            self.month = month
            self.day = day
    
        @classmethod
        def from_string(cls, date_string):
            year, month, day = map(int, date_string.split('-'))
            return cls(year, month, day)
    
    # 使用类方法创建实例
    date = Date.from_string("2023-11-15")
    

    2. 访问和修改类状态

    当方法需要操作类级别而非实例级别的数据时:

    class Employee:
        raise_amount = 1.04  # 类变量
    
        @classmethod
        def set_raise_amount(cls, amount):
            cls.raise_amount = amount
    
    # 修改所有员工的加薪比例
    Employee.set_raise_amount(1.05)
    

    3. 继承中的多态行为

    类方法在继承体系中保持多态特性:

    class Parent:
        @classmethod
        def factory(cls):
            print("Parent factory")
            return cls()
    
    class Child(Parent):
        @classmethod
        def factory(cls):
            print("Child factory")
            return cls()
    
    # 调用时会根据实际类执行相应方法
    obj = Child.factory()  # 输出"Child factory"
    

    与静态方法的区别:

    1. 参数不同:类方法接收cls参数,静态方法无特殊参数
    2. 继承行为:类方法可以被子类覆盖,静态方法不能
    3. 访问权限:类方法可以访问类状态,静态方法不能
    class Example:
        @classmethod
        def class_method(cls):
            print(f"Called from {cls.__name__}")
    
        @staticmethod
        def static_method():
            print("Static method called")
    

    你可能感兴趣的:(Python,python,开发语言)