Глава 9 • Классы
class Car():
...
class Battery():
"""Простая модель аккумулятора электромобиля."""
def __init__(self, battery_size=70):
"""Инициализирует атрибуты аккумулятора."""
self.battery_size = battery_size
def describe_battery(self):
"""Выводит информацию о мощности аккумулятора."""
print("This car has a " + str(self.battery_size) + "-kWh battery.")
class ElectricCar(Car):
"""Представляет аспекты машины, специфические для электромобилей."""
def __init__(self, make, model, year):
"""
Инициализирует атрибуты класса-родителя.
Затем инициализирует атрибуты, специфические для электромобиля.
"""
super().__init__(make, model, year)
self.battery = Battery()
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.battery.describe_battery()
В точке
определяется новый класс с именем
Battery
, который не наследует
ни от одного из других классов. Метод
__init__()
в точке
получает один пара-
метр
battery_size
, кроме
self
. Если значение не предоставлено, этот необязатель-
ный параметр задает
battery_size
значение 70. Метод
describe_battery()
также
перемещен в этот класс
.
Затем в класс
ElectricCar
добавляется атрибут с именем
self.battery
. Эта стро-
ка приказывает Python создать новый экземпляр
Battery
(со значением
battery_
size
по умолчанию, равным 70, потому что значение не задано) и сохранить его
в атрибуте
self.battery
. Это будет происходить при каждом вызове
__init__()
;
теперь любой экземпляр
ElectricCar
будет иметь автоматически создаваемый
экземпляр
Battery
.
Программа создает экземпляр электромобиля и сохраняет его в переменной
my_
tesla
. Когда потребуется вывести описание аккумулятора, необходимо обратиться
к атрибуту
battery
:
my_tesla.battery.describe_battery()
Эта строка приказывает Python обратиться к экземпляру
my_tesla
, найти его
атрибут
battery
и вызвать метод
describe_battery()
, связанный с экземпляром
Battery
из атрибута.
Результат выглядит так же, как и в предыдущей версии:
2016 Tesla Model S
This car has a 70-kWh battery.
Наследование
175
Казалось бы, новый вариант требует большой дополнительной работы, но теперь
аккумулятор можно моделировать с любой степенью детализации без загромож-
дения класса
ElectricCar
. Добавим в
Battery
еще один метод, который выводит
запас хода на основании мощности аккумулятора:
class Car():
...
class Battery():
...
def get_range(self):
"""Выводит приблизительный запас хода для аккумулятора."""
if self.battery_size == 70:
range = 240
elif self.battery_size == 85:
range = 270
message = "This car can go approximately " + str(range)
message += " miles on a full charge."
print(message)
class ElectricCar(Car):
...
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()
в точке
проводит простой анализ. Если мощность рав-
на 70, то
get_range()
устанавливает запас хода 240 миль, а при мощности 85 kWh
запас хода равен 270 милям. Затем программа выводит это значение. Когда вы
захотите использовать этот метод, его придется вызывать через атрибут
battery
в точке
.
Результат сообщает запас хода машины в зависимости от мощности аккумулятора:
2016 Tesla Model S
This car has a 70-kWh battery.
This car can go approximately 240 miles on a full charge.
Моделирование объектов реального мира
Занявшись моделированием более сложных объектов — таких, как электромо-
били, — вы столкнетесь со множеством интересных вопросов. Является ли запас
хода электромобиля свойством аккумулятора или машины? Если вы описываете
только одну машину, вероятно, можно связать метод
get_range()
с классом
Battery
.
Но, если моделируется целая линейка машин от производителя, вероятно, метод
get_range()
правильнее будет переместить в класс
ElectricCar
. Метод
get_range()
по-прежнему будет проверять мощность аккумулятора перед определением за-
паса хода, но он будет сообщать запас хода для той машины, с которой он связан.
176
Достарыңызбен бөлісу: |