15 类的继承——创建子类

9.3 类的继承

编写类时可以使用已经编写好的类(类似于调用)时就要用到继承。
一个类继承另一个类:原有的类称为【父类】,新的类叫做【子类】。
子类将获得父类的所有【属性和方法】,并且子类还可以定义自己的属性和方法;在子类中也可以修改父类中的【方法】。

1 创建子类的方法

下面还是以上篇中汽车的类为父类,创建它的子类。
#*******************这一段是之前创建的汽车类**********************#
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())
#注意这里的get_descriptive_name()函数是从新创建的子类里调用的!

Result

2016 Tesla Model S

【注意点】:
①创建子类时父类必须包含在当前界面
②必须在子类的括号中指明父类的名称class ElectricCar(Car):
③第一个方法__init__接受创建Car类所需的信息(注意这儿有self
super()函数是让子类和父类连接起来,就是调用父类的【方法】__init__(注意这儿没有self
⑤创建实例的时候调用子类 --- 子类自动向父类寻找

2 当然你还可以给子类新增属于他自己的【方法和属性】

#*******************这一段是之前创建的汽车类**********************#
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) 
        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() #调用新的方法describe_battery()

Result:

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


3 还可以更改父类已有的方法

#*******************这一段是之前创建的汽车类**********************#
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) 
        self.battery_size = 70    #新增的子类属性,需要初始化
    
    #下面我们开始创建新的方法来表述这个电瓶的相关信息
    def describe_battery(self):
        """打印一条描述电瓶容量的消息"""
        print("This car has a " + str(self.battery_size) + "-KWh battery.")
        
    #更改父类已有的属性(重新定义即可) --- 假设父类有 fill_gas_tank这一方法
    def fill_gas_tank(self):
        """电动汽车没有油箱"""
        print("This car doesn't need a gas tank!")
        
#开始创建实例 --- 假设调用了方法fill_gas_tank
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name()) #用于返回整洁的信息
my_tesla.describe_battery() #调用新的方法describe_battery()
my_tesla.fill_gas_tank()    #假设我们调用了fill_gas_tank方法查看油箱信息
【子类既可以新增也可以修改】就是继承可以对父类 --- 取其精华,去其糟粕

Result:

2016 Tesla Model S
This car has a 70-KWh battery.
This car doesn't need a gas tank!


4 有时候类中的【方法】太多,总会让人不想看下去,为此可以将类的一部分提取出来作为新的类——意思就是再细分类。

例如将ElectricCar类中的关于电池的一些方法划分成一个新类 --- Battery类
#*******************这一段是之前创建的汽车类**********************#
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 Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
    
    def __init__(self, battery_size=70):#初始化形参的值时最好不要加空格!
        """初始化电瓶的属性"""            #在这里我们定义了一个可选形参battery_size
        self.battery_size = battery_size
        
    def describe_battery(self):
        """打印一条描述电池容量的信息"""
        print("This car has a " + str(self.battery_size) + "-KWh batttery.")
#************************以下是子类****************************#    
class ElectricCar(Car):
    """电动汽车的独特之处"""
    
    def __init__(self, make, model, year):
        """
        电动汽车的独特之处
        初始化父类的属性,再初始化子类的属性
        """    
        super().__init__(make, model, year) 
        self.battery = Battery()   #****直接将 Battery类作为其中的一个[方法]****#
        
#开始创建实例
my_tesla = ElectricCar('tesla', 'model s', 2016)

print(my_tesla.get_descriptive_name()) #用于返回整洁的信息
my_tesla.battery.describe_battery() 
#调用battery就是调用类 Battery,Battery再调用其中的describe_battery()来描述电瓶

Result:

2016 Tesla Model S
This car has a 70-KWh batttery.


5 下面再给Battery类添加一个【方法】,使它能够根据电池容量大小报告可行驶的里程数。

#*******************这一段是之前创建的汽车类**********************#
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 Battery():
    """一次模拟电动汽车电瓶的简单尝试"""
    
    def __init__(self, battery_size=70):#初始化形参的值时最好不要加空格!
        """初始化电瓶的属性"""          #在这里我们定义了一个[可选]形参battery_size
        self.battery_size = battery_size
        
    def describe_battery(self):
        """打印一条描述电池容量的信息"""
        print("This car has a " + str(self.battery_size) + "-KWh batttery.")
        
    def get_range(self):
        """打印一条消息,指出电瓶的续航里程数"""
        if self.battery_size == 70:
            range = 240
        elif self.battery_size == 85:         #elif后是必须加条件的
            range = 270
            
        message = "This car can go approximately " + str(range)
        message += " miles on a full charge." #字符串的连接方式
        print(message)
#************************以下是子类****************************#    
class ElectricCar(Car):
    """电动汽车的独特之处"""
    
    def __init__(self, make, model, year):
        """
        电动汽车的独特之处
        初始化父类的属性,再初始化子类的属性
        """    
        super().__init__(make, model, year) 
        self.battery = Battery() #****直接将 Battery类作为其中的一个[方法]****#
        
#开始创建实例
my_tesla = ElectricCar('tesla', 'model s', 2016)

print(my_tesla.get_descriptive_name()) #用于返回整洁的信息
my_tesla.battery.describe_battery() 
my_tesla.battery.get_range()
【注意最后调用的时】:
get_range( )函数在Battery类里的,在ElectricCar类里已经将Battery类作为了其一个方法——self.battery = Battery( ),所以可以直接调用battery( )

Result:

2016 Tesla Model S
This car has a 70-KWh batttery.
This car can go approximately 240 miles on a full charge.


6 动手试一试 --- 冰淇淋小店

#**********************以下是餐馆的类**********************#
class Restaurant():
    """餐馆的简介"""
    
    def __init__(self, restaurant_name, cuisine_type):
        """初始化餐馆的属性name和type"""
        self.name = restaurant_name #注意后面的名称是形参 --- 这里是初始化的形参
        self.type = cuisine_type    #用self,使下面的所有方法都可使用初始化的形参
        
    def describe_restaurant(self):
        """描述餐馆的信息"""
        print(self.name.title() + " is the type of " + self.type +'.')
        
    def open_restaurant(self):
        """餐馆营业时间"""
        print(self.name.title() + " is open from 8 am to 10 PM.\n" )
#**********************下面尝试编写其子类**********************#
class IceCreamStand(Restaurant):
    """冰淇淋小店重现"""
    
    def __init__(self, restaurant_name, cuisine_type):
        """初始化父类的属性"""
        super().__init__(restaurant_name, cuisine_type) #用super()函数连接父类
        self.icecream_flavors = [
                                  'original', 
                                 'chocolate',
                                     'mocha', 
                                 'strawberry'
                                 ]
        
#现在这个子类具有了父类的所有方法和属性,让我们来增加一些方法
    def flavors(self):
        """显示冰淇淋的口味列表"""
        print("It has the following tastes icecream:")
        for icecream_flavor in self.icecream_flavors:
            print(icecream_flavor)
            
#************************下面创建实例***********************#    
restaurant = IceCreamStand('cold-drink shop', 'fruity')
#先调用父类的方法试试
restaurant.describe_restaurant()
restaurant.open_restaurant()
#下面调用子类新增的方法
restaurant.flavors()

Result:

Cold-Drink Shop is the type of fruity.
Cold-Drink Shop is open from 8 am to 10 PM.

It has the following tastes icecream:
original
chocolate
mocha
strawberry

【在初始化的时候要特别注意 】:
1.super().__init__(形参1 ,形参2)的形式 —— 与父类连接
2.子类新增方法时,要现在初始化代码下”声明“ —— self.icecream_flavors = ...
3.在使用属性时候要加self—— for icecream_flavor in self.icecream_flavors:

最后也想不起来说啥,看到的就提前祝你猪(* ̄(oo) ̄)年大吉吧!

7df9446e6c0aee5a4cea61e984bb2ad6.jpg

你可能感兴趣的:(15 类的继承——创建子类)