Python 面向对象进阶

15.1 继承

继承允许一个类获取另一个类的属性和方法。

基本语法

1
2
3
4
5
class 父类:
pass

class 子类(父类):
pass

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Animal:
def __init__(self, name):
self.name = name

def speak(self):
print(f"{self.name} 发出声音")

class Dog(Animal):
def bark(self):
print(f"{self.name} 汪汪叫!")

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

dog = Dog("旺财")
dog.speak() # 旺财 发出声音
dog.bark() # 旺财 汪汪叫!

cat = Cat("小白")
cat.speak() # 小白 发出声音
cat.meow() # 小白 喵喵叫!

15.2 方法重写

子类可以重写父类的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Animal:
def __init__(self, name):
self.name = name

def speak(self):
print(f"{self.name} 发出声音")

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

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

animals = [Dog("旺财"), Cat("小白"), Dog("大黄")]
for animal in animals:
animal.speak()
# 输出:
# 旺财 汪汪叫!
# 小白 喵喵叫!
# 大黄 汪汪叫!

15.3 super() 函数

super() 用于调用父类方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def introduce(self):
print(f"我是{self.name}{self.age}岁")

class Student(Person):
def __init__(self, name, age, student_id):
super().__init__(name, age) # 调用父类构造
self.student_id = student_id

def introduce(self):
super().introduce() # 调用父类方法
print(f"学号: {self.student_id}")

s = Student("Alice", 20, "2024001")
s.introduce()
# 输出:
# 我是Alice,20岁
# 学号: 2024001

15.4 多态

多态允许不同类的对象对同一消息做出不同响应。

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
class Shape:
def area(self):
pass

class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height

def area(self):
return self.width * self.height

class Circle(Shape):
def __init__(self, radius):
self.radius = radius

def area(self):
import math
return math.pi * self.radius ** 2

def print_area(shape):
print(f"面积: {shape.area():.2f}")

rect = Rectangle(5, 3)
circle = Circle(4)

print_area(rect) # 面积: 15.00
print_area(circle) # 面积: 50.27

15.5 多重继承

Python 支持一个类继承多个父类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Flyer:
def fly(self):
print("飞行中...")

class Swimmer:
def swim(self):
print("游泳中...")

class Duck(Flyer, Swimmer):
def quack(self):
print("嘎嘎叫!")

duck = Duck()
duck.fly() # 飞行中...
duck.swim() # 游泳中...
duck.quack() # 嘎嘎叫!

MRO(方法解析顺序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A:
def process(self):
print("A")

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

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

class D(B, C):
pass

d = D()
d.process() # B(按 MRO 顺序)
print(D.mro()) # 查看解析顺序

15.6 类方法作为替代构造器

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
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

@classmethod
def from_string(cls, date_str):
year, month, day = map(int, date_str.split("-"))
return cls(year, month, day)

@classmethod
def today(cls):
import datetime
now = datetime.date.today()
return cls(now.year, now.month, now.day)

def __str__(self):
return f"{self.year}-{self.month:02d}-{self.day:02d}"

d1 = Date(2024, 11, 30)
d2 = Date.from_string("2024-11-30")
d3 = Date.today()

print(d1) # 2024-11-30
print(d2) # 2024-11-30
print(d3) # 当前日期

15.7 组合 vs 继承

组合(Has-A 关系)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Engine:
def start(self):
print("引擎启动")

class Car:
def __init__(self):
self.engine = Engine() # 组合

def start(self):
self.engine.start()
print("汽车启动")

car = Car()
car.start()

选择建议

  • 继承:Is-A 关系(狗是动物)
  • 组合:Has-A 关系(汽车有引擎)
  • 优先使用组合,更灵活

15.8 类型检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Animal:
pass

class Dog(Animal):
pass

dog = Dog()

# isinstance() - 检查实例
print(isinstance(dog, Dog)) # True
print(isinstance(dog, Animal)) # True
print(isinstance(dog, object)) # True

# issubclass() - 检查类继承
print(issubclass(Dog, Animal)) # True
print(issubclass(Animal, Dog)) # False

15.9 本章小结

  • 继承实现代码复用,子类可重写父类方法
  • super() 调用父类方法
  • 多态允许不同类响应同一方法
  • 支持多重继承,注意 MRO 顺序
  • 类方法可作为替代构造器
  • 优先使用组合而非继承
  • isinstance()issubclass() 用于类型检查

练习题

  1. 创建 Vehicle 基类,派生 CarBike
  2. 创建 Employee 类,派生 ManagerDeveloper
  3. 使用多态实现不同形状的面积计算
  4. 以下代码输出什么?
    1
    2
    3
    4
    5
    6
    7
    class A:
    def show(self):
    print("A")
    class B(A):
    pass
    b = B()
    print(isinstance(b, A))
ByteFisher
分享编程技术 · 记录钓鱼乐趣
扫码关注
▸ 扫码关注 ◂
Python基础教程 系列
第 15/20 篇
分享: