Инкапсуляция является ключевым принципом объектно-ориентированного программирования (ООП), который помогает защитить данные объекта и предоставляет контролируемый доступ к этим данным через методы класса. Давайте рассмотрим более подробные примеры, чтобы лучше понять, как это работает в Python.
Класс
Car
с инкапсуляциейclass Car:
def __init__(self, make, model, year):
self.__make = make # Инкапсулированное свойство
self.__model = model
self.__year = year
def get_make(self):
return self.__make
def get_model(self):
return self.__model
def get_year(self):
return self.__year
def set_make(self, make):
self.__make = make
def set_model(self, model):
self.__model = model
def set_year(self, year):
self.__year = year
def display_info(self):
print(f"Make: {self.__make}, Model: {self.__model}, Year: {self.__year}")
# Создание объекта и доступ к его методам и атрибутам через интерфейс
car = Car("Toyota", "Camry", 2020)
car.display_info() # Вывод: Make: Toyota, Model: Camry, Year: 2020
# Изменение атрибутов через методы
car.set_year(2021)
car.display_info() # Вывод: Make: Toyota, Model: Camry, Year: 2021
# Попытка доступа к атрибутам напрямую вызовет ошибку
# print(car.__make) # AttributeError: 'Car' object has no attribute '__make'
В этом примере свойства
make
, model
и year
инкапсулированы с использованием двойного подчеркивания __
, что делает их закрытыми для прямого доступа извне класса. Вместо этого мы предоставляем публичные методы get_
и set_
для получения и изменения значений этих атрибутов.Класс
Employee
с инкапсуляциейclass Employee:
def __init__(self, name, age, salary):
self.__name = name
self.__age = age
self.__salary = salary
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def get_salary(self):
return self.__salary
def set_name(self, name):
self.__name = name
def set_age(self, age):
if age > 0:
self.__age = age
def set_salary(self, salary):
if salary > 0:
self.__salary = salary
def display_info(self):
print(f"Name: {self.__name}, Age: {self.__age}, Salary: ${self.__salary}")
# Создание объекта и доступ к его методам и атрибутам через интерфейс
employee = Employee("John", 30, 50000)
employee.display_info() # Вывод: Name: John, Age: 30, Salary: $50000
# Изменение атрибутов через методы
employee.set_salary(60000)
employee.display_info() # Вывод: Name: John, Age: 30, Salary: $60000
# Попытка доступа к атрибутам напрямую вызовет ошибку
# print(employee.__name) # AttributeError: 'Employee' object has no attribute '__name'
Класс
BankAccount
с инкапсуляциейРассмотрим пример банковского счёта, где баланс и операции над ним инкапсулированы для защиты данных.
class BankAccount:
def __init__(self, account_number, balance=0):
self.__account_number = account_number
self.__balance = balance
def get_account_number(self):
return self.__account_number
def get_balance(self):
return self.__balance
def deposit(self, amount):
if amount > 0:
self.__balance += amount
else:
print("Amount must be positive.")
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
else:
print("Invalid withdrawal amount.")
def display_info(self):
print(f"Account Number: {self.__account_number}, Balance: ${self.__balance}")
# Создание объекта и доступ к его методам и атрибутам через интерфейс
account = BankAccount("12345678", 1000)
account.display_info() # Вывод: Account Number: 12345678, Balance: $1000
# Внесение депозита
account.deposit(500)
account.display_info() # Вывод: Account Number: 12345678, Balance: $1500
# Снятие средств
account.withdraw(300)
account.display_info() # Вывод: Account Number: 12345678, Balance: $1200
# Попытка доступа к атрибутам напрямую вызовет ошибку
# print(account.__balance) # AttributeError: 'BankAccount' object has no attribute '__balance'
Класс
Student
с инкапсуляцией и проверкамиРассмотрим класс
Student
, который инкапсулирует информацию о студенте и проводит проверки при изменении данных.class Student:
def __init__(self, name, age, grade):
self.__name = name
self.__age = age
self.__grade = grade
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def get_grade(self):
return self.__grade
def set_name(self, name):
if name:
self.__name = name
def set_age(self, age):
if age > 0:
self.__age = age
def set_grade(self, grade):
if 0 <= grade <= 100:
self.__grade = grade
def display_info(self):
print(f"Name: {self.__name}, Age: {self.__age}, Grade: {self.__grade}")
# Создание объекта и доступ к его методам и атрибутам через интерфейс
student = Student("Alice", 20, 90)
student.display_info() # Вывод: Name: Alice, Age: 20, Grade: 90
# Изменение атрибутов через методы
student.set_grade(95)
student.display_info() # Вывод: Name: Alice, Age: 20, Grade: 95
# Попытка установки некорректного значения
student.set_grade(105) # Некорректное значение, не изменит grade
student.display_info() # Вывод: Name: Alice, Age: 20, Grade: 95
# Попытка доступа к атрибутам напрямую вызовет ошибку
# print(student.__grade) # AttributeError: 'Student' object has no attribute '__grade'