Python面向对象中类的继承(第4节)


在Python中,面向对象编程的特点在于,它具有封装继承多态三大特性。通过高度封装性、灵活的继承性和强大的多态性,可以使程序更加高效、结构清晰,并方便管理和扩展。

类的继承

面向对象中的继承和现实生活中的继承相同,比如儿子继承父亲的财产等。面向对象中的继承是指一个类可以从另一个类中继承属性和方法。继承是一种创建新的类的方式,新创建的类叫子类,继承的类叫父类、超类、基类。继承允许子类继承父类的属性和方法,并且可以在子类中添加新的属性和方法,或者修改继承的属性和方法。

Python中定义子类的语法如下:

class 子类名父类名1父类名2):
 语法块

在子类的定义中,可以在子类名后的圆括号中指定要继承的父类。如果有多个父类,父类名之间用逗号隔开。

动手练一练:

# 定义一个名为Person的类
class Person:
    # 初始化函数(构造函数)
    def __init__(self, name):
        self.name = name   # 将传入的参数赋值给类的属性name
    def say(self):   # 定义成员方法
        print("你好!我是", self.name)

class Student(Person):
    pass

student = Student("张三")
student.say()

执行以上代码,输出结果为:

你好我是 张三

上面的例子中,在Person类中我们定义了name属性和say()方法,但是在Student类中什么都没有定义。由于Student是从Person继承下来的子类,所以Student同样拥有name属性和say()方法。上面的例子中可以看出,继承允许子类重用父类的代码,从而减少了代码的重复性。我们可以继续定义Child,Boy等子类并从Person继承name属性和say()方法,大大减少了代码量。

这里需要注意的是,如果子类中定义了自己的构造方法,那么父类的构造方法“_init_”就不会自动调用。需要在子类的构造方法中用super函数专门调用。例如:

动手练一练:

# 定义一个名为Person的类
class Person:
    # 初始化函数(构造函数)
    def __init__(self, name):
        self.name = name   # 将传入的参数赋值给类的属性name
    def say(self):   # 定义成员方法
        print("你好!我是", self.name)

class Student(Person):
    def __init__(self):
        print("你好!我是学生")

student = Student("张三")
student.say()

执行以上代码,输出结果为:

TypeError: __init__() takes 1 positional argument but 2 were given

上面的例子中,Python解释器输出错误信息“类型错误:_init_()采用1个位置参数,但给出了2个”。说明“Person”类中的构造方法“_init_()”没有被执行,我们可以在“Student”类的构造方法中用super()函数专门调用。例如:

动手练一练:

# 定义一个名为Person的类
class Person:
    # 初始化函数(构造函数)
    def __init__(self, name):
        self.name = name   # 将传入的参数赋值给类的属性name
    def say(self):   # 定义成员方法
        print("你好!我是", self.name)

class Student(Person):
    def __init__(self):
        super(Student, self).__init__("张三")

student = Student()
student.say()

执行以上代码,输出结果为:

你好我是 张三

上面的例子中,在“Student”类的构造方法中用super()函数专门调用父类的构造方法之后运行正常。

还有一点需要注意的是,子类不能继承父类中的私有属性和方法,也不能在自己的方法内部访问父类的私有属性和方法。例如:

动手练一练:

# 定义一个名为Person的类
class Person:
    # 初始化函数(构造函数)
    def __init__(self, name):
        self.__name = name
    def __say(self):
        print("这是__say私有方法")
    def say(self):
        self.__say()
        print("这是私有属性", self.__name)

class Student(Person):
    def __init__(self):
        super(Student, self).__init__("张三")
    def call(self):
        self.__say()    # 错误 

student = Student()
student.say()   # 输出 “这是__say私有方法”和“这是私有属性 张三”
student.call()    # 错误

执行以上代码,输出结果为:

这是__say私有方法
这是私有属性 张三
AttributeError: 'Student' object has no attribute '_Student__say'

上面的例子中,Python解释器输出错误信息“属性错误:‘Student’对象没有属性‘_Student__say’”,但是成功继承了父类中say()方法,说明在子类中是不能继承父类的私有属性和方法的,但是私有属性和方法可以在同一个类中被调用。

Python中类的继承还可以一级接着一级地往下继承,就好比从爷爷到爸爸、再到儿子这样的继承关系。而任何类,最终都可以追溯到根类“object”,这些继承关系看上去就像一颗倒着的树。