May 29, 2024

Урок: Объектно-ориентированное программирование (ООП)

Основы ООП: классы и объекты

Объектно-ориентированное программирование (ООП) — это парадигма программирования, в которой основные концепции основаны на объектах и классах. В этом уроке мы рассмотрим основные концепции ООП: классы и объекты, наследование и полиморфизм, инкапсуляцию и абстракцию.

  1. Классы и объекты:

Класс — это шаблон для создания объектов (экземпляров класса). Объекты содержат данные (атрибуты) и поведение (методы).

Пример определения класса
class Dog:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def bark(self):
        print(f"{self.name} says woof!")

# Создание объекта (экземпляра класса)
my_dog = Dog("Buddy", 3)

# Доступ к атрибутам и методам объекта
print(my_dog.name)  # Выводит: Buddy
print(my_dog.age)   # Выводит: 3
my_dog.bark()       # Выводит: Buddy says woof!

В этом примере определяется класс Dog с конструктором __init__, который инициализирует атрибуты name и age. Метод bark выводит сообщение. Создается объект my_dog, и через него можно получить доступ к атрибутам и методам класса.

Наследование и полиморфизм

Наследование позволяет создавать новый класс на основе существующего. Полиморфизм позволяет использовать одно и то же имя метода для различных классов.

  1. Наследование:
Пример наследования
class Animal:
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return f"{self.name} says woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says meow!"

my_dog = Dog("Buddy")
my_cat = Cat("Whiskers")

print(my_dog.speak())  # Выводит: Buddy says woof!
print(my_cat.speak())  # Выводит: Whiskers says meow!

В этом примере класс Animal является базовым классом, от которого наследуются классы Dog и Cat. Каждый подкласс реализует метод speak по-своему.

  1. Полиморфизм:
Пример полиморфизма
animals = [Dog("Buddy"), Cat("Whiskers")]

for animal in animals:
    print(animal.speak())
# Выводит:
# Buddy says woof!
# Whiskers says meow!

В этом примере используется полиморфизм для вызова метода speak у объектов разных классов, которые наследуют от одного базового класса Animal.

Инкапсуляция и абстракция

Инкапсуляция скрывает внутренние детали реализации от внешнего мира, предоставляя доступ только через методы класса. Абстракция позволяет создавать сложные системы, сокрывая детали реализации и предоставляя простой интерфейс.

  1. Инкапсуляция:
Пример инкапсуляции
class BankAccount:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.__balance = balance  # Приватный атрибут

    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount

    def withdraw(self, amount):
        if amount <= self.__balance:
            self.__balance -= amount
        else:
            print("Недостаточно средств")

    def get_balance(self):
        return self.__balance

account = BankAccount("Alice", 100)
account.deposit(50)
account.withdraw(30)
print(account.get_balance())  # Выводит: 120

В этом примере атрибут __balance является приватным и доступен только внутри класса BankAccount. Доступ к балансу осуществляется через методы deposit, withdraw и get_balance.

  1. Абстракция:

Абстракция достигается путем использования классов и методов, которые скрывают сложные детали и предоставляют простой интерфейс для взаимодействия.

Пример абстракции
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14159 * (self.radius ** 2)

shapes = [Rectangle(2, 3), Circle(5)]

for shape in shapes:
    print(shape.area())
# Выводит:
# 6
# 78.53975

В этом примере используется абстрактный класс Shape с абстрактным методом area. Классы Rectangle и Circle наследуют от Shape и реализуют метод area, скрывая сложные детали вычислений.

Практическое задание

  1. Создайте класс Car с атрибутами make, model и year, и методом display_info.
  2. Создайте подкласс ElectricCar, который наследует от Car, и добавьте атрибут battery_size и метод display_battery.
  3. Создайте класс Person с приватным атрибутом age и методами для установки и получения возраста.
  4. Создайте абстрактный класс Employee с абстрактным методом calculate_salary, и подклассы Manager и Developer, которые реализуют этот метод.
Пример выполнения практического задания

# Задание 1
class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
    
    def display_info(self):
        print(f"{self.year} {self.make} {self.model}")

# Задание 2
class ElectricCar(Car):
    def __init__(self, make, model, year, battery_size):
        super().__init__(make, model, year)
        self.battery_size = battery_size
    
    def display_battery(self):
        print(f"Battery size: {self.battery_size} kWh")

my_car = ElectricCar("Tesla", "Model S", 2020, 100)
my_car.display_info()          # Выводит: 2020 Tesla Model S
my_car.display_battery()       # Выводит: Battery size: 100 kWh

# Задание 3
class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age  # Приватный атрибут
    
    def set_age(self, age):
        if age > 0:
            self.__age = age
    
    def get_age(self):
        return self.__age

person = Person("Alice", 30)
print(person.get_age())  # Выводит: 30
person.set_age(35)
print(person.get_age())  # Выводит: 35

# Задание 4
from abc import ABC, abstractmethod

class Employee(ABC):
    @abstractmethod
    def calculate_salary(self):
        pass

class Manager(Employee):
    def __init__(self, base_salary, bonus):
        self.base_salary = base_salary
        self.bonus = bonus
    
    def calculate_salary(self):
        return self.base_salary + self.bonus

class Developer(Employee):
    def __init__(self, base_salary, overtime):
        self.base_salary = base_salary
        self.overtime = overtime
    
    def calculate_salary(self):
        return self.base_salary + (self.overtime * 20)

manager = Manager(5000, 1500)
developer = Developer(4000, 10)

print(manager.calculate_salary())  # Выводит: 6500
print(developer.calculate_salary())  # Выводит: 4200

В первом задании создается класс Car с атрибутами и методом для отображения информации. Во втором задании создается подкласс ElectricCar, который добавляет новый атрибут и метод. В третьем задании создается класс Person с приватным атрибутом и методами для управления возрастом. В четвертом задании создается абстрактный класс Employee и два подкласса, которые реализуют метод для вычисления зарплаты.

Этот урок охватывает основные аспекты ООП в Python, включая классы и объекты, наследование и полиморфизм, инкапсуляцию и абстракцию. Практикуйтесь для лучшего понимания и освоения материала.