一、类继承的概念
类是Python中最标准的面向对象编程模式。在Python中,可以使用类继承的方式来实现代码的重用和抽象化,让类之间形成父子关系,通过子类从父类继承属性和方法,可以大大简化代码的编写和管理,在代码维护和升级方面具备很大的优势。
类继承指的是在一个已有的类(父类)的基础上,定义出一个新的类(子类),使得子类拥有父类的所有属性和方法,同时也可以添加自己的属性和方法,但是不会影响到父类的结构和功能。
<!-- 父类 -->
class Animal:
def __init__(self, name):
self.name = name
def run(self):
print(self.name + "正在奔跑...")
<!-- 子类 -->
class Dog(Animal):
def bark(self):
print(self.name + "正在汪汪叫...")
dog = Dog("小狗")
dog.bark() # "小狗正在汪汪叫..."
dog.run() # "小狗正在奔跑..."
以上代码中定义了两个类——Animal(动物)和Dog(狗),Dog是Animal的子类,它继承了Animal类的方法和属性。当实例化Dog类的对象时,可以调用Dog类自己和它的父类的方法。
二、类继承的分类
类继承按照实现方式可以分为两类:
- 单继承:子类只继承一个父类。
- 多继承:子类同时继承多个父类。
在Python中支持多重继承。虽然有时候多重继承会带来不必要的麻烦,但是它也为我们实现程序的复用、抽象化和模块化提供了新的思路。
下面是一个多重继承的示例:
<!-- 第一个父类 -->
class Animal:
def __init__(self, name):
self.name = name
def run(self):
print(self.name + "正在奔跑...")
<!-- 第二个父类 -->
class Swiming:
def swim(self):
print(self.name + "正在游泳...")
<!-- 子类 -->
class Duck(Animal, Swiming):
pass
duck = Duck("小鸭")
duck.run() # "小鸭正在奔跑..."
duck.swim() # "小鸭正在游泳..."
以上示例中,Duck类同时继承了Animal类和Swiming类,所以Duck类实例化的对象拥有了两个父类的属性和方法。
三、类继承的高级用法
面向对象编程还有一些高级的用法,比如方法重写、继承顺序、抽象类等,这些技巧可以让我们更好地应用类继承实现代码的重用和抽象化。
1、方法重写
当子类需要修改父类中的某个方法时,可以使用方法重写(Override)的方式。
<!-- 父类 -->
class Person:
def say_hello(self):
print("你好!")
<!-- 子类 -->
class Chinese(Person):
def say_hello(self):
print("你好,我是中国人!")
class English(Person):
pass
chinese = Chinese()
chinese.say_hello() # "你好,我是中国人!"
english = English()
english.say_hello() # "你好!"
在以上示例中,Chinese类重写了Person类的say_hello方法,所以调用对象的say_hello方法时输出的是子类的方法,而English类没有重写该方法,所以调用对象的say_hello方法时输出的是父类的方法。
2、继承顺序
在子类继承多个父类时,Python会按照一定的搜索顺序来查找父类中的方法和属性。
搜索顺序如下:
- 自下而上,自左而右,遇到第一个匹配就停止搜索。
- 如果两个父类继承同一个父类,则优先选择前面的父类。
<!-- 第一个父类 -->
class A():
def foo(self):
print('A')
<!-- 第二个父类 -->
class B():
def foo(self):
print('B')
<!-- 子类 -->
class C(A, B):
pass
c = C()
c.foo() # 输出A
可以看到,当子类没有重写父类的方法时,Python会按照搜索顺序使用先继承的父类的方法。
3、抽象类
抽象类是一个特殊的类,它不能被实例化,只能被继承。抽象类定义了一个抽象接口,子类必须实现该接口中的所有方法才能够被实例化。
在Python中,可以使用abc模块来定义抽象类。
import abc
<!-- 抽象类 -->
class Shape(metaclass=abc.ABCMeta):
@abc.abstractmethod
def area(self):
pass
<!-- 子类 -->
class Rectangle(Shape):
def area(self):
return self.width * self.height
rec = Rectangle()
rec.width = 5
rec.height = 7
print("面积:", rec.area())
以上示例中,Shape类是一个抽象类,它定义了一个抽象方法area。Rectangle类继承了Shape类,并重写了area方法,所以它可以被实例化。
四、总结
类继承是Python中最基本也最常用的面向对象编程特性之一,它可以实现代码的重用和抽象化,使得代码更加易读、易维护和易拓展。在编写程序时,我们应该合理地应用类继承,通过多态等高级的技巧来设计出优雅、简洁、可扩展的程序。