объектно-ориентированное программирование на Python | Часть — 1

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

Если вы попытаетесь поискать в Интернете или в любых учебниках, то конкретного определения ООП нет. В общем, объектно-ориентированное программирование концептуализируется как комбинация 4 базовых концепций. Эти понятия таковы:

  1. Абстракция (Что-то скрыть)
  2. Инкапсуляция (для инкапсуляции или объединения многих вещей)
  3. Наследование (Наследовать что-либо)
  4. Полиморфизм (для использования во многих целях)

Я объясню эти концепции подробно по мере продвижения блога. Но главное, что нужно знать в ООП, это Классы и объекты. Итак, что же это за классы и объекты?

Класс и объект в Python

Проще говоря, класс — это просто скелет или структура реальной вещи (объекта). Например, эскиз/контур здания — это класс, тогда как фактическое здание — это объект.

Синтаксис для создания класса:

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

Теперь, если мы применим эту концепцию класса-объекта ко всем людям, тогда мы можем иметь Person как класс со многими свойствами и функциями.

class Person:
  age = 30
  height = 180
  weight = 65
  def say_hello(self):
	print('Hello Person')

Здесь мы создали класс Person со свойствами возраст, рост и вес, а также метод или функциональность say_hello(). Мы создали этот класс Person, что теперь?

Чтобы использовать этот класс человека, нам нужно создать объект из этого класса Person. Для создания объекта мы используем следующий синтаксис:

object_name = ClassName()

Чтобы создать объект класса Person:

person = Person()
print(person)
""" OUTPUT:
<__main__.Person object at 0x000001C47ED317B0>
"""

Когда мы пытаемся напечатать person, мы видим, что это объект класса Person, расположенный в памяти по адресу 0x000001C47ED317B0. Чтобы использовать свойство и методы класса, мы можем использовать следующий синтаксис:

class Person:
  age = 30
  height = 180
  weight = 65
  def say_hello(self):
	print('Hello Person')
person = Person()
print("AGE:", person.age)
print("HEIGHT:", person.height)
print("WEIGHt:", person.weight)
person.say_hello()
""" OUTPUT: 
AGE: 30
HEIGHT: 180
WEIGHt: 65
Hello Person
"""

Этот класс Person выглядит очень статичным и с фиксированной функциональностью, тогда почему я назвал его схемой/схемой, спросите вы?

Я намеренно сделал класс Person простым, чтобы показать вам основное использование класса и объектов. Итак, если бы я показал вам правильное, но простое использование класса и объекта, тогда:

class Person:
  def __init__(self, name, age, height, weight):
	self.name  = name 
	self.age = age
	self.height = height
	self.weight = weight
 def show_data(self):
	print('Details: ')
	print('AGE:', self.age)
	print('HEIGHT:', self.height, "cm")
	print('WEIGHt:', self.weight, "kg")
person1 = Person('John Doe', 33, 180, 75)
person1.show_data()
print("-"*15)
person2 = Person('Jane Doe', 31, 160, 65)
person2.show_data()
""" OUTPUT:
Details: 
NAME: John Doe
AGE: 33
HEIGHT: 180 cm
WEIGHt: 75 kg
---------------
Details: 
NAME: Jane Doe
AGE: 31
HEIGHT: 160 cm
WEIGHt: 65 kg
"""

Как вы можете видеть в приведенном выше примере кода, я смог передать разные значения для имени, возраста, роста и веса и создал 2 объекта из класса Person. Я могу передавать одинаковые или разные значения в соответствии со своими потребностями и создавать N объектов, потому что они все равно будут храниться в разных местах.

person1 = Person('John Doe', 33, 180, 75)
print(person1)
# OUTPUT: <__main__.Person object at 0x000001E6B1C93FA0>
person2 = Person('Jane Doe', 31, 160, 65)
print(person2)
# OUTPUT: <__main__.Person object at 0x000001E6B1C93EB0>
person3 = Person('Jane Doe', 31, 160, 65)
print(person3)
# OUTPUT: <__main__.Person object at 0x000001E6B1C93E50>

В реальном сценарии, когда нам нужно создать несколько пользователей (функция регистрации), мы не пишем код для каждого пользователя. Мы используем класс и создаем объекты на основе полученных деталей, как мы это делали с person1 и person2.

Теперь вы могли заметить ключевое слово self и метод __init__() в приведенном выше коде. Итак, что это?

Что такое метод init() в Python?

Если вы работаете с другими языками, такими как Java, C# или JavaScript, вы можете быть знакомы с концепцией конструктора. Метод init() — это конструктор класса в Python. Для нетехнических людей рассматривайте конструктор как способ сказать компилятору/интерпретатору инициировать операцию или выделить память объекту, который мы планируем создать. Но нет необходимости использовать конструктор в Python. Если мы не предоставим метод __init__(), интерпретатор создаст сам.

Обычно мы используем метод init() для инициализации некоторых свойств и для целей наследования. Как мы видели ранее, вот как мы инициализируем переменные:

def __init__(self, name, age, height, weight):
  self.name  = name 
  self.age = age
  self.height = height
  self.weight = weight

Примечание. Мы обсудим, как использовать метод __init__() для наследования позже.

Теперь вы можете спросить, но, Сахил, что такое, черт возьми, self?

Что такое ключевое слово «я» в Python?

Ключевое слово self представляет экземпляр класса. (Просто для простоты рассмотрите экземпляр как объект, сгенерированный интерпретатором. Объекты и экземпляры — это не одно и то же, но здесь считайте их одним и тем же, просто для простоты понимания.)

Используя это ключевое слово self, мы можем получить доступ ко всем атрибутам/свойствам и методам класса. Например, в приведенном ниже примере мы использовали ключевое слово self для доступа к имени, возрасту, росту и весу. атрибуты.

class Person:
 def __init__(self, name, age, height, weight):
	self.name  = name 
	self.age = age
	self.height = height
	self.weight = weight
  def show_data(self):
	print('Details: ')
	print('NAME:', self.name)
	print('AGE:', self.age)
	print('HEIGHT:', self.height, "cm")
	print('WEIGHt:', self.weight, "kg")

Мы также можем получить доступ к методам, используя ключевое слово self.

class Person:
  def __init__(self, name, age, height, weight):
	self.name  = name 
	self.age = age
	self.height = height
	self.weight = weight
  def show_data(self):
	print('Details: ')
	print('NAME:', self.name)
	print('AGE:', self.age)
	print('HEIGHT:', self.height, "cm")
	print('WEIGHt:', self.weight, "kg")
  def self_demo(self):
	self.show_data()
person1 = Person('John Doe', 33, 180, 75)
person1.self_demo()
""" OUTPUT:
Details: 
NAME: John Doe
AGE: 33
HEIGHT: 180 cm
WEIGHt: 75 kg
"""

Нет необходимости использовать ключевое слово self. Вы можете использовать любое имя, но при условии, что оно должно быть первым аргументом метода. (Также и для **init**().)

class Person:
  def __init__(random_replacement, name):
	random_replacement.name = name
	pass
  def show_data(random_replacement_1):
	print('Just a Random Thing!')
	print('Name:', random_replacement_1.name)
person1 = Person('John Doe')
person1.show_data()
""" OUTPUT:
Just a Random Thing!
Name: John Doe
"""

Как вы могли догадаться, также не обязательно использовать одно и то же имя в классе. Единственное и единственное правило состоит в том, что it should be the first argument! Но, как правило, предпочитают ключевое слово self, так как оно стало почти стандартом. Если мы хотим передать какой-либо аргумент, мы должны передать его после ключевого слова self. Как мы делали в методе __init__().

Вы также можете добавить любой атрибут в любое время, используя ключевое слово self.

class Person:
  def __init__(self, name):
	self.name = name
  def add_age(self, age):
	self.age = age
  def show_data(self):
	print('Name:', self.name)
	print('Age:', self.age)
person1 = Person('John Doe')
person1.add_age(31)
person1.show_data()
""" OUTPUT:
Name: John Doe
Age: 31
"""

Здесь мы добавили возраст к атрибутам класса. Я не предлагаю вам делать это, но просто для демонстрационных целей, что это возможно. Рассматривайте ключевое слово self как словарь, а все атрибуты и методы как key этого словаря.

В приведенном выше примере кода, если мы сначала вызовем метод show_data(). Это выдаст ошибку, так как в это время у нас нет атрибута с именем age.

Этот процесс объединения атрибутов и методов под одним зонтиком называется инкапсуляцией.

Итак, как нам расширить использование и функциональность нашего класса? Мы можем сделать это, используя Inheritance и Polymorphism.

Наследование в Python

Как следует из названия, наследование — это возможность что-то наследовать. В этом случае мы будем наследовать атрибуты и методы. Например, ранее мы создали класс с именем Person, который является слишком общим. Но используя этот общий класс, мы можем создать другой класс, который будет соответствовать нашим потребностям.

Мы хотим создать класс Employee, который наследует все или наследуется от класса Person. Итак, как мы это делаем?

Синтаксис наследования в Python:

# Base Class/Parent Class
class BaseClass:
    <statement-1>
    .
    <statement-N>
# Derived Class/Child Class
class DerivedClass(BaseClass):
    <statement-1>
    .
    <statement-N>

Чтобы создать класс Employee из класса Person, мы можем написать следующий код:

class Person:
  def __init__(self, name, age, height, weight):
	self.name  = name
	self.age = age
	self.height = height
	self.weight = weight
  def show_basic_data(self):
	print('Details: ')
	print('NAME:', self.name)
	print('AGE:', self.age)
	print('HEIGHT:', self.height, "cm")
	print('WEIGHt:', self.weight, "kg")
class Employee(Person):
  def __init__(self, employeeId, department, salary):
	super().__init__(name, age, height, weight) 
	self.employeeId = employeeId
	self.department = department
	self.salary = salary
  def show_data(self):
	self.show_basic_data()
	print('Employee Id:', self.employeeId)
	print('Department:', self.department)
	print('salary: $', self.salary)
employee = Employee('John Doe', 33, 180, 75, 1 ,'IT', 100000)
employee.show_data()
""" OUTPUT:
Details: 
NAME: John Doe
AGE: 33
HEIGHT: 180 cm
WEIGHt: 75 kg
Employee Id: 1
Department: IT
salary: $ 100000
"""

Вы могли заметить super() в классе Employee. Что это за super() спросите вы? Ключевое слово super относится к родительскому классу. Мы используем метод super() для доступа к атрибутам и методам родительского класса. Именно это мы и сделали в методе __init__() класса Employee. Мы передали некоторые данные родительскому классу.

Как только мы вызвали super() в методе __init__() дочернего класса, мы можем использовать все атрибуты и методы родительского класса в нашем дочернем классе. Это то, что мы сделали в методе show_data() класса Employee. Мы могли бы также использовать super().show_basic_data().

Заключение

Окончательно! Мы в конце этого раздела 😁.

Вот оно. Спасибо за чтение.

Дайте мне знать, если вам нужна помощь или вы хотите что-то обсудить. Свяжитесь со мной в Twitter или LinkedIn. Не забудьте оставить любые мысли, вопросы или опасения в комментариях ниже. Я хотел бы увидеть их.

Вы можете узнать больше об ООП на Википедии или GeeksforGeeks.

Хотите узнать больше?

Подпишитесь на мою Информационную рассылку и получайте лучшие статьи на свой почтовый ящик.

До следующего раза 👋

Познакомьтесь с другими моими блогами из серии Python 101