python面向对象(二)继承:最直接的代码复用

继承简介
继承是指通过在创建类时提供另一个类(称为父类)的名称,来获取父类的属性与方法。继承最明显的作用就是节约代码量,不需要重复定义已经存在的属性与方法。但是深入思考就会发现,复用只是继承的附带作用,继承最有意义的一点,是将不同的类联系了起来,让不同的类之间能够有一定的共性。当我们在面对不同类的时候,如果能按照他们的共性按图索骥,那么会轻松不少。例如,如果我们已经考取了c1驾照,当我们看到半挂卡车的时候,即使没有开过,也可以立即理解其操作方式,从而节省了学习时间。
私有与重写
在python中,继承的内容可以是属性也可以是方法。有时候我们不想让一个类的某些属性或者方法暴露在外(即通过【对象名.属性】或者【对象名.方法名()】的方式查看或调用),或者不希望被子类继承,则可以用私有或者重写的方式来在某种程度上达到我们的目标。私有属性在命名时以两个下划线开头,私有属性或方法不可以在直接访问(也不可以在子类中直接访问),而是必须要采用一些被额外定义的公共方法访问。举个例子:

点击查看代码
class Student(object):
    def __init__(self):
        self.sid = ''
        self.gender = ''
        self.__university = '清华大学'   
class HighSchoolStudent(Student):
    pass
上文的例子中,学生类有一个属性sid,子类HighSchoolStudent继承了这个属性(高中生也会有学号)。然而,并不适合所有学生都上过大学,高中生类显然没有从学生类中继承到university属性。如果我们试图获取这个属性,结果会是AttributeError: 'HighSchoolStudent' object has no attribute '__university'的属性错误。 现在让我们为学生类添加一个方法,来查看学生的目标大学。
点击查看代码
class Student(object):
    def __init__(self):
        self.sid = ''
        self.gender = ''
        self.__university = '清华大学'
    def TargetSchool(self):
        print(f'我将努力学习,争取{self.__university}的offer!')
class HighSchoolStudent(Student):
    pass
此时,继承了HighSchoolStudent方法的高中生,即使不能直接查看有__university属性,也可以用继承来的方法TargetSchool来查看目标学校。 然而,不是所有人都把目标定为清华大学,此时我们就需要在实例中修改属性和方法。不管是属性还是方法,如果在子类中重新定义了同名内容,那么最终使用的是子类中定义的方法,这叫做重写。我们可以通过重写TargetSchool来改变目标学校,这里就不再演示。然而要注意的是,我们重写的方法,是无法通过正常的属性访问方式来获取__university属性的,因为它被私有了。访问这类私有属性通常也是不合适的,如果真的需要,可以用self._定义类名(在这里是_Student)__university 的方式强制访问。 到这里,继承的作用已经较为清晰,我们可以对子类对象直接使用父类方法而不需要重新定义,我们也可以重写父类方法来获得不同于父类的行为或属性。还有一点不完美:一名高中生除了是学生,可能还是某个独立游戏的开发者。如果我们有如下定义:
点击查看代码
class Programmer(object):
    def __init__(self):
        self.gender = 'male'
        language = 'Python'
    def coding(self):
        print(f'写{self.language}代码')
那么如何利用这个类让这名高中生也可以身兼数职呢?答案是多继承,也就是同时让其继承两个或更多的父类。
点击查看代码
class HighSchoolStudent(Student,Programmer):
    pass
现在高中生也可以写代码了。但是一个新的问题出现了,学生类和程序员类都有一个属性gender,高中生会有两个同名属性吗?答案是不会的。同名情况下,高中生只会获得继承顺序靠前的父类的属性和方法。我们可以用类名.__mro__ 属性来查看继承的顺序。 继承的内容到这里基本就告一段落了,总结一下,继承主要是关于子类调用父类的内容,这个过程中可以重写其内容。私有属性或方法可以让我们不对外暴露,同样也可以让子类无法直接继承。
posted @ 2024-04-07 09:39  小丑与锁鸟  阅读(7)  评论(0编辑  收藏  举报