【Python 1-16】Python手把手教程之——类Class的继承、父类、子类

做者 | 弗拉德
来源 | 弗拉德(公众号:fulade_me)bash

继承

编写类时,并不是老是要从空白开始。若是你要编写的类是另外一个现成类的特殊版本,可以使用 继承。一个类继承另外一个类时,它将自动得到另外一个类的全部属性和方法;原有的类称为父类, 而新类称为子类。子类继承了其父类的全部属性和方法,同时还能够定义本身的属性和方法。dom

子类的方法__init__()

建立子类的实例时,Python首先须要完成的任务是给父类的全部属性赋值。为此,子类的方法__init__()须要继承父类的方法。
例如,下面来模拟电动汽车。电动汽车是一种特殊的汽车,所以咱们能够在前面建立的Car类的基础上建立新类ElectricCar,这样咱们就只需为电动汽车特有的属性和行为编写代码。
下面来建立一个简单的ElectricCar类版本,它具有Car类的全部功能:函数

class Car(): 
    """一次模拟汽车的简单尝试"""
    def __init__(self, make, model, year): 
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0
    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model 
        return long_name.title()

    def read_odometer(self):
        print("This car has " + str(self.odometer_reading) + " miles on it.")

    def update_odometer(self, mileage):
        if mileage >= self.odometer_reading:
            self.odometer_reading = mileage 
        else:
            print("You can't roll back an odometer!")

    def increment_odometer(self, miles): 
        self.odometer_reading += miles


class ElectricCar(Car): 
    """电动汽车的独特之处"""
    def __init__(self, make, model, year): 
        """初始化父类的属性"""
        super().__init__(make, model, year) 
        
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())

首先是Car类的代码。建立子类时,父类必须包含在当前文件中,且位于子类前面。接着咱们定义了子类ElectricCar。定义子类时,必须在括号内指定父类的名称。方法__init__() 接受建立Car实例所需的信息。测试

ElectricCar内部的super()是一个特殊函数,帮助Python将父类和子类关联起来。这行代码让Python调用ElectricCar的父类的方法__init__(),让ElectricCar实例包含父类的全部属性。父类也称为超类(superclass),名称super所以而得名。spa

接下来咱们测试一下继承的做用,咱们尝试建立一辆电动汽车,但提供的信息与建立普通汽车时相同。咱们建立ElectricCar类的一个实例,并将其存储在变量my_tesla中。这行代码调用ElectricCar类中定义的方法__init__(),后者让Python调用父类Car中定义的方法 __init__()。咱们提供了实参'tesla'、'model s'和2016。
除方法__init__()外,电动汽车没有其余特有的属性和方法。当前,咱们只想确认电动汽车具有普通汽车的行为,输出结果以下:code

2016 Tesla Model S

ElectricCar实例的行为与Car实例同样,如今能够开始定义电动汽车特有的属性和方法了。继承

给子类定义属性和方法

让一个类继承另外一个类后,可添加区分子类和父类所需的新属性和方法。
下面来添加一个电动汽车特有的属性(电瓶),以及一个描述该属性的方法。咱们将存储电瓶容量,并编写一个打印电瓶描述的方法:ip

class ElectricCar(Car):
    def __init__(self, make, model, year):
        """电动汽车的独特之处 初始化父类的属性,再初始化电动汽车特有的属性 """
        super().__init__(make, model, year) 
        self.battery_size = 70
    def describe_battery(self): 
        """打印一条描述电瓶容量的消息"""
        print("This car has a " + str(self.battery_size) + "-kWh battery.")

my_tesla = ElectricCar('tesla', 'model s', 2016) 
print(my_tesla.get_descriptive_name()) 
my_tesla.describe_battery()

咱们添加了新属性self.battery_size,并设置其初始值。根据ElectricCar类建立的全部实例都将包含这个属性,但全部Car实例都不包含它。咱们还添加了一个名为describe_battery()的方法,它打印有关电瓶的信息。咱们调用这个方法时,将看到一条电动汽车特有的描述:rem

2016 Tesla Model S
This car has a 70-kWh battery.

对于ElectricCar类的特殊化程度没有任何限制。模拟电动汽车时,你能够根据所需的准确程度添加任意数量的属性和方法。若是一个属性或方法是任何汽车都有的,而不是电动汽车特有的,就应将其加入到Car类而不是ElectricCar类中。这样,使用Car类的人将得到相应的功能,而 ElectricCar类只包含处理电动汽车特有属性和行为的代码。get

重写父类的方法

对于父类的方法,只要它不符合子类模拟的实物的行为,均可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
假设Car类有一个名为fill_gas_tank()的方法,它对全电动汽车来讲毫无心义,所以你可能想重写它。下面演示了一种重写方式:

def ElectricCar(Car):
    def fill_gas_tank():
        """电动汽车没有油箱"""
        print("This car doesn't need a gas tank!")

如今,若是有人对电动汽车调用方法fill_gas_tank(),Python将忽略Car类中的方法fill_gas_tank(),转而运行上述代码。使用继承时,可以让子类保留从父类那里继承的有用的代码,用重写来覆盖不须要的代码。

本篇文章没有做业,下一篇咱们讲解函数的高级用法

公众号

相关文章
相关标签/搜索