Python 进阶突破面向对象——继承(Inheritance)详解

liftword2周前 (04-28)技术文章1

继承是面向对象编程的四大支柱之一,它允许我们基于现有类创建新类,新类会继承父类的属性和方法,同时可以添加或修改功能。

一、继承的基本概念

1. 基本语法

class ParentClass:
    # 父类定义
    pass

class ChildClass(ParentClass):
    # 子类定义
    pass

2. 简单示例

class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        print(f"{self.name} makes a sound")

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

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

# 使用示例
animal = Animal("Generic Animal")
animal.speak()  # Generic Animal makes a sound

dog = Dog("Buddy")
dog.speak()     # Buddy says woof!

cat = Cat("Whiskers")
cat.speak()     # Whiskers says meow!

二、继承的类型

1. 单继承

一个子类只继承一个父类(Python默认支持)

class Parent:
    def parent_method(self):
        print("Parent method")

class Child(Parent):
    def child_method(self):
        print("Child method")

c = Child()
c.parent_method()  # 继承自Parent
c.child_method()   # 自己的方法

2. 多继承

一个子类可以继承多个父类

class Father:
    def father_method(self):
        print("Father's method")

class Mother:
    def mother_method(self):
        print("Mother's method")

class Child(Father, Mother):
    def child_method(self):
        print("Child's method")

c = Child()
c.father_method()  # 继承自Father
c.mother_method()  # 继承自Mother
c.child_method()   # 自己的方法

3. 多层继承(继承链)

class Grandparent:
    def grandparent_method(self):
        print("Grandparent's method")

class Parent(Grandparent):
    def parent_method(self):
        print("Parent's method")

class Child(Parent):
    def child_method(self):
        print("Child's method")

c = Child()
c.grandparent_method()  # 继承自Grandparent
c.parent_method()       # 继承自Parent
c.child_method()        # 自己的方法

三、方法重写(Override)

子类可以重写父类的方法以改变其行为

class Vehicle:
    def __init__(self, brand):
        self.brand = brand
    
    def drive(self):
        print(f"{self.brand} is driving")

class Car(Vehicle):
    def drive(self):  # 重写父类方法
        print(f"{self.brand} car is driving fast!")

class Truck(Vehicle):
    def drive(self):  # 重写父类方法
        print(f"{self.brand} truck is driving slowly")

v = Vehicle("Generic")
v.drive()  # Generic is driving

c = Car("Toyota")
c.drive()  # Toyota car is driving fast!

t = Truck("Volvo")
t.drive()  # Volvo truck is driving slowly

四、super()函数

super()用于调用父类的方法,常用于:

  1. 访问被重写的父类方法
  2. 在子类__init__中调用父类初始化方法
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def display_info(self):
        print(f"Name: {self.name}, Age: {self.age}")

class Student(Person):
    def __init__(self, name, age, student_id):
        super().__init__(name, age)  # 调用父类的__init__
        self.student_id = student_id
    
    def display_info(self):
        super().display_info()  # 调用父类的display_info
        print(f"Student ID: {self.student_id}")

s = Student("Alice", 20, "S12345")
s.display_info()
# 输出:
# Name: Alice, Age: 20
# Student ID: S12345

五、方法解析顺序(MRO)

在多重继承中,Python使用C3线性化算法确定方法调用顺序,可以通过__mro__属性或mro()方法查看

class A:
    def method(self):
        print("A method")

class B(A):
    def method(self):
        print("B method")

class C(A):
    def method(self):
        print("C method")

class D(B, C):
    pass

print(D.__mro__)
# 输出: (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

d = D()
d.method()  # 输出: B method (按照MRO顺序查找)

六、抽象基类(ABC)

使用abc模块可以定义抽象基类,强制子类实现特定方法

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass
    
    @abstractmethod
    def perimeter(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height
    
    def perimeter(self):
        return 2 * (self.width + self.height)

# 必须实现所有抽象方法,否则会报错
r = Rectangle(5, 3)
print(r.area())      # 15
print(r.perimeter()) # 16

七、继承的实际应用示例

# 员工管理系统示例
class Employee:
    def __init__(self, name, employee_id):
        self.name = name
        self.employee_id = employee_id
    
    def display_info(self):
        print(f"Employee: {self.name}, ID: {self.employee_id}")
    
    def calculate_salary(self):
        raise NotImplementedError("Subclass must implement this method")

class FullTimeEmployee(Employee):
    def __init__(self, name, employee_id, monthly_salary):
        super().__init__(name, employee_id)
        self.monthly_salary = monthly_salary
    
    def calculate_salary(self):
        return self.monthly_salary

class PartTimeEmployee(Employee):
    def __init__(self, name, employee_id, hours_worked, hourly_rate):
        super().__init__(name, employee_id)
        self.hours_worked = hours_worked
        self.hourly_rate = hourly_rate
    
    def calculate_salary(self):
        return self.hours_worked * self.hourly_rate

# 使用示例
full_time = FullTimeEmployee("Alice", "FT001", 5000)
part_time = PartTimeEmployee("Bob", "PT001", 80, 20)

employees = [full_time, part_time]

for emp in employees:
    emp.display_info()
    print(f"Salary: ${emp.calculate_salary()}")
    print("-" * 30)

继承是代码复用的强大工具,合理使用继承可以:

  1. 减少代码重复
  2. 提高代码可维护性
  3. 建立清晰的类层次结构
  4. 实现多态行为

但也要注意不要过度使用继承,有时组合(composition)可能是更好的选择。

相关文章

三十二、Python类的继承与多继承详解

继承是面向对象的三大特征之一,也是实现软件复用的重要途径。Python中的继承机制是多继承机制,即一个子类可以同时有多个父类。1.继承的语法Python子类继承父类的语法是在定义子类时,将多个父类放在...

Python | 多继承(python多继承父类参数问题)

在Python中,类可以继承自多个类。这被称为多继承。多继承是一种非常强大的概念,它允许我们将多个类的功能组合到一个类中。在本文中,我们将使用一个简单的示例来说明多继承的概念。假设我们正在编写一个图形...

python多继承的3C算法是什么?怎么用?

有很多地方都说python多继承的继承顺序,是按照深度遍历的方式,其实python多继承顺序的算法,不是严格意义上的深度遍历,而是基于深度遍历基础上优化出一种叫3C算法python多继承的深度遍历cl...

python之多态、继承、重写篇(python多态的作用特点)

# -*- coding: UTF-8 -*- class Animal: def run(self): print("动物会跑。。") def sl...

Python 中的继承和多态(python多继承的顺序)

Python 中的继承是什么?Python 中的继承是一个特性,允许一个类(子类)使用另一个类(父类)的属性和方法。这有助于我们重用代码并避免重复。思考一下亲子关系:孩子继承了父母的某些特征,但也可以...

python继承与多态-多继承二义性和弊端

在Python中,多继承是一种同时从多个父类继承属性和方法的机制。然而,多继承也可能导致二义性和带来一些弊端。下面我们来详细说明这些问题。二义性(Ambiguity)当一个类从多个父类继承了相同的方法...