- Объяснять понятия класса и объекта
- Писать класс с
__init__, атрибутами и методами - Использовать наследование и переопределять методы
Ты пишешь электронный журнал: у каждого ученика есть имя, класс и оценки, нужно добавлять новые оценки и считать средний балл. Для 30 учеников отдельные переменные и функции быстро превращаются в путаницу. Объектно-ориентированное программирование (ООП) предлагает другой путь: объединить данные и функции, работающие с ними, в один «пакет» — объект.
Класс и объект
Класс — это чертёж объектов: он описывает, какие данные будут у каждого объекта и что он умеет делать. Объект — конкретный экземпляр, созданный по этому чертежу. Как по одному чертежу можно построить много домов, так из одного класса можно создать сколько угодно объектов.
| Термин | Значение | В примере |
|---|---|---|
| Класс | чертёж объектов | Student |
| Объект | экземпляр, созданный из класса | aysel |
| Атрибут | переменная внутри объекта | self.name |
| Метод | функция внутри объекта | average() |
Первый класс
class Student:
def __init__(self, name, grade):
self.name = name
self.grade = grade
self.scores = []
def add_score(self, score):
self.scores.append(score)
def average(self):
return sum(self.scores) / len(self.scores)
def __str__(self):
return f'{self.name} (grade {self.grade})'
aysel = Student('Aysel', 8)
murad = Student('Murad', 9)
aysel.add_score(5)
aysel.add_score(4)
murad.add_score(3)
print(aysel, aysel.scores)
print(murad, murad.scores)
print('Average:', aysel.average())▸ Ожидаемый результат
Aysel (grade 8) [5, 4] Murad (grade 9) [3] Average: 4.5
class Student:определяет новый класс. Имена классов обычно пишут с заглавной буквы.__init__— особый метод, конструктор: он вызывается автоматически при записиStudent('Aysel', 8)и задаёт атрибуты объекта.self— это сам объект, у которого вызван метод. При записиaysel.add_score(5)self— этоaysel.__str__определяет, как объект будет выглядеть при выводе черезprint.
Обрати внимание: aysel и murad созданы из одного класса, но у каждого свой список оценок. Добавление оценки одному не влияет на другого — объекты независимы.
Наследование
Наследование позволяет создать новый класс на основе существующего. Дочерний класс получает все атрибуты и методы родительского и может переопределить нужные. Ниже классы Dog и Cat берут метод introduce у Animal в готовом виде, а метод speak заменяют своим:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return '...'
def introduce(self):
return f'I am {self.name} and I say {self.speak()}'
class Dog(Animal):
def speak(self):
return 'Woof!'
class Cat(Animal):
def speak(self):
return 'Meow!'
for pet in [Dog('Rex'), Cat('Mestan'), Animal('Nemo')]:
print(pet.introduce())▸ Ожидаемый результат
I am Rex and I say Woof! I am Mestan and I say Meow! I am Nemo and I say ...
Один и тот же вызов introduce() дал для каждого объекта разный результат, потому что каждый объект использует свой метод speak. Это свойство называется полиморфизмом. Если дочернему классу нужен новый атрибут, в его __init__ сначала вызывают конструктор родителя через super().__init__(...):
class Animal:
def __init__(self, name):
self.name = name
class Parrot(Animal):
def __init__(self, name, words):
super().__init__(name)
self.words = words
def talk(self):
return self.name + ' says ' + ' and '.join(self.words)
tutu = Parrot('Tutu', ['hello', 'salam'])
print(tutu.talk())
print(isinstance(tutu, Animal))▸ Ожидаемый результат
Tutu says hello and salam True
Напиши класс Player: __init__ сохраняет имя и устанавливает score в 0, метод add_points(points) увеличивает счёт, а __str__ возвращает текст вида Aysel: 25 points. Нижняя часть заготовки проверяет класс — не меняй её.
class Player:
# __init__(self, name): save the name, set score to 0
# add_points(self, points): add points to score
# __str__(self): return text like Aysel: 25 points
pass
aysel = Player('Aysel')
murad = Player('Murad')
aysel.add_points(10)
aysel.add_points(15)
murad.add_points(20)
print(aysel)
print(murad)▸ Ожидаемый результат
Aysel: 25 points Murad: 20 points
Класс Shape уже готов. Создай от него два подкласса: Square (со стороной side) и Rectangle (с width и height). Каждый должен передать своё имя ('Square', 'Rectangle') через super().__init__() и определить свой метод area(). Затем выведи результат describe() для Square(4) и Rectangle(5, 3).
class Shape:
def __init__(self, name):
self.name = name
def area(self):
return 0
def describe(self):
return f'{self.name}: area {self.area()}'
# 1) class Square(Shape) with side; area = side * side
# 2) class Rectangle(Shape) with width and height
# 3) print describe() for Square(4) and Rectangle(5, 3)▸ Ожидаемый результат
Square: area 16 Rectangle: area 15
Главное
- Класс — чертёж, объект — его конкретный экземпляр.
__init__вызывается автоматически при создании объекта и задаёт его атрибуты.- Первый параметр метода —
self, объект, у которого вызван метод. class Dog(Animal):— наследование:Dogполучает всё от родителя и может переопределять методы.super().__init__()вызывает конструктор родителя из дочернего класса.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.