8.0、Python基础---类(浅读)(中)

8.4、继承

一个类继承另一个类时,它将自动获得另一个类的所有的属性和方法;原有的类称为父类,而新类称为子类。子类继承了其父类的所有的属性和方法,同时还可以定义自己的属性和方法。
什么是继承?
继承是一种创建新的类的方式,新创建的叫子类,继承的叫父类、超类、基类。
特点:子类可以使用父类的属性
继承是类与类之间的关系
好处:减少代码的冗余、提高重用性
定义如下:

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

父类定义在另一个模块中可以用下面方法继承

class DerivedClassName(modname.BaseClassName):

8.4.1、子类的__init__()方法

创建子类的实例时,Python首先需要完成的任务是给父类的所有属性赋值。为此,子类的方法__init__()需要父类施以援手。
比如,下面来模拟地动汽车。电动汽车是一种特殊的汽车,因此我们可以在前面创建的Car类的基础上创建新类ElectricCar,这样只需为电动汽车特有的属性和行为编写代码。
如下所示:

class Car():
    """模拟汽车 -> make :制作 ;model:模型;year:年份"""
    def __init__(self,make,model,year):
        """初始化描述汽车的属性"""
        self.make = make  # 制作
        self.model = model # 模型
        self.year = year # 年份
        self.odometer = 0

    def get_read_odometer(self):
        """获取汽车的里程信息"""
        print("此款"+self.make+self.model+
              '型车已行驶'+str(self.odometer) + '公里')

    def update_orometer(self,mileage):
        """
        将里程表读数设置为指定的值
        禁止将里程表数让回调
        """
        if mileage >= self.odometer:
            self.odometer = mileage
        else:
            print("您的操作无效")

    def increment_odometer(self,miles):
        """将里程表读数增加指定的量"""
        self.odometer += miles

    def get_car_information(self):
        """返回一些描述汽车的信息"""
        mesg_name = '生产于:'+str(self.year)+'年 --> 类型:'+self.make+' --> 型号:'+self.model
        return mesg_name

    def print_info(self):
        """打印汽车信息方法"""
        return print(self.get_car_information())

class ElectricCar(Car):
    """电动汽车类"""
    def __init__(self,make,model,year):
        """初始化父类的属性"""
        super().__init__(make,model,year)

my_tesla = ElectricCar('小刀','no3',2030)
print(my_tesla.get_car_information())

运行结果:

生产于:2030--> 类型:小刀 --> 型号:no3

代码解析:
首先是Car类的代码,创建子类时,父类必须包含在当前文件中,且位于子类前面。定义子类时,必须在括号中指定父类的名称。方法init()接收创建Car实例所需的信息。
super()是一个特殊函数,帮助Python将父类和子类关联起来。这句代码就是调用ElectricCar的父类的方法init(),让ElectricCar实例报案父类的所有属性。

8.4.2、给子类定义属性和方法

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

class ElectricCar(Car):
    """电动汽车类"""
    def __init__(self,make,model,year):
        """
        初始化父类的属性
        初始化父类的属性,再初始化电动车特有的属性
        """
        super().__init__(make,model,year)
        self.battery_value = 80
    def get_battery(self):
        """获取电瓶容量信息"""
        print('此辆电动汽车电量值为:'+str(self.battery_value)+'-kWh')
    

my_tesla = ElectricCar('小刀','no3',2030)
print(my_tesla.get_car_information())
my_tesla.get_battery()

运行结果:

生产于:2030--> 类型:小刀 --> 型号:no3
此辆电动汽车电量值为:80-kWh

模拟电动汽车时候,你可以根据所需的准确程度添加数量的属性和方法。如果一个属性或方法是任何汽车都有的,而不是电动汽车特有的,就应该将其加入到Car类而不是ElectricCar类中。这样,使用Car类的人将获得相应的功能,而ElectricCar类只包含处理电动汽车所特有的属性和行为的代码。

8.4.3、重写父类的方法

对于父类的方法,只要它不符合子类模拟的实物的行为,都可对其进行重写。为此,可在子类中定义一个这样的方法,即它与要重写的父类方法同名。这样,Python将不会考虑这个父类方法,而只关注你在子类中定义的相应方法。
假设Car类中有个方法,他对电动汽车没有意义,因此可以在子类中重写它。

class Car():
	----
	def fill_gas_tank(self):
    """模拟父类中fill_gas_tank()方法"""
    print("父类--->这个汽车没有油箱!")

class ElectricCar(Car):
	----
    def fill_gas_tank(self):
    """模拟子类重写父类中的fill_gas_tank()方法"""
	print("子类--->电动汽车没有油箱")
	

运行结果:

生产于:2030--> 类型:小刀 --> 型号:no3
此辆电动汽车电量值为:80-kWh
子类--->电动汽车没有油箱

小结:使用继承,可让子类保留从父类那里继承过来的精华,并剔除不需要的糟粕。

8.4.4、将实例作为属性

使用代码模拟实体实物时,你可能会发现自己给类添加的细节越来越多,属性和方法清单以及文件都越来越长。在这种情况下,可能需要将类的一部分作为一个独立的类提取出来。这样就可将大型的类拆分成多个协同工作的小类。
例如,不断给ElectricCar类添加细节时候,这样类中包含了很多专门针对汽车电瓶的属性和方法。这种情况下,我们可以将这些属性和方法提取出来,放到另一个名为Battery的类中,并将一个battery实例用作ElectricCar类的一个属性。

class Car():
	----


class Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
    def __init__(self,battery_value = 70):
        """初始化电瓶的属性"""
        self.battery_value = battery_value

    def describe_battery(self):
        """打印电瓶容量的信息"""
        print('这个电瓶电量:'+str(self.battery_value)+'-kWh')

class ElectricCar(Car):
    """电动汽车类"""
	def __init__(self,make,model,year):
        """
        初始化父类的属性
        初始化父类的属性,再初始化电动车特有的属性
        """
        super().__init__(make,model,year)
        self.battery = Battery() # 是电瓶类

# 测试方法
my_tes = ElectricCar('劳斯莱斯','野牛3号',2020)
print(my_tes.get_car_information())
my_tes.battery.describe_battery()

运行结果:

生产于:2020--> 类型:劳斯莱斯 --> 型号:野牛3号
这个电瓶电量:70-kWh

代码解析:
首先定义了一个叫Battery的类,它没有继承任何类。此类中初始化方法中的形参,除了self之外,还有另一个形参是battery_value。这个形参是可选的,如果调用时没有给传递参数,则显示默认值。并且describe_battery()方法也移到这个类中。
在ElectricCar类中初始化方法中,添加了一个名叫self.batttery的属性。self.battery = Battery()此行代码是先创建一个新的Battery实例,并将实例存储到self.battery中。每当方法init()被调用时,都将执行该操作。因此现在每个ElectricCar实例都包含一个自动创建的Battery实例。
这时我们创建了一辆电动汽车,并将其存到变量my_tes中。要想描述电瓶时,就需要使用电瓶汽车的属性battery(my_tes.battery.describe_battery()),此行代码就是让Python在实例my_tes中查找属性battery,并对存在该属性中的Battery实例调用方法describe_battery()方法。
这样做的目的主要是为了让代码更加清晰、整洁。
下面再给Battery类添加一个方法,他根据电瓶容量报告汽车的续航里程:

class Car():
	----
class Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
    ----
    def get_range(self):
        """获取电瓶的续航里程"""
        if self.battery_value == 70:
            range = 240
        elif self.battery_value == 85:
            range = 270
            
        message = '此电瓶续航 '+str(range)
        message += ' -公里'
        print(message)

class ElectricCar(Car):
    """电动汽车类"""
    ----

my_tes = ElectricCar('劳斯莱斯','野牛3号',2020)
print(my_tes.get_car_information())
my_tes.battery.describe_battery()
my_tes.battery.get_range()

运行结果:

生产于:2020--> 类型:劳斯莱斯 --> 型号:野牛3号
这个电瓶电量:70-kWh
此电瓶续航 240 -公里

共勉:
每天进步一点点

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 书香水墨 设计师:CSDN官方博客 返回首页