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