Автор: Галих

Содержание:
● Конструктор и деструктор
● Инкапсуляция
● Сеттер и геттер
● Наследование
● Метод переопределения и перегрузки (полиморфизм )
● Абстрактный класс
● Класс интерфейса
● Статический метод
● Волшебный метод
● Перегрузка оператора
● Супер()
● Множественный Наследование
● Порядок разрешения методов

● Конструктор и деструктор

Конструктор и деструктор на самом деле является методом в парадигме объектно-ориентированного программирования, который есть не только в python. Этот метод может быть чем-то, что должно существовать в структуре создания класса.

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

Конструктор обычно используется для выполнения начального процесса подготовки объекта, такого как присвоение значений свойствам, вызов внутренних методов и ряд других процессов, которые считаются необходимыми. В Python метод __init__() называется контроллером и всегда вызывается при создании объекта.

def __init__(self):
 # body of the constructor

Деструктор служит для окончательной очистки перед тем, как объект будет полностью удален из памяти. Например, закрытие соединения с базой данных, закрытие файлов, открытых в данный момент, или очистка кеша во время работы приложения.

Чтобы удалить его, используйте команду del. Функция деструктора в python называется __del__(), это волшебный метод, процесс вызова которого выполняется системой автоматически. даже если на самом деле без вызова функции del, если у класса есть деструктор, то после того, как программы больше не будут запущены, все переменные будут уничтожены автоматически.

● Инкапсуляция

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

В python доступно 3 модификатора доступа:

1. Публичный

К переменным или атрибутам, имеющим права общего доступа, можно получить доступ откуда угодно, как извне класса, так и изнутри класса. Рассмотрим следующий пример:

2. Защищено

Доступ к переменным или атрибутам, имеющим защищенные права доступа, возможен только ограниченным образом сами по себе (т. е. внутри внутреннего класса), а также из их производных классов.

Чтобы определить атрибут с защищенными привилегиями, мы должны использовать префикс подчеркивания _ перед именем переменной.

class Modifiers:
 def __init__(self, name):
 self._protected_member = name 
 
 m = Modifiers("Galih")
 print(m._protected_member)
 m._protected_member = "Ngekho"
 print(m._protected_member)

3. Частный

Следующий модификатор является приватным. Каждая переменная в классе, имеющая приватные права доступа, доступна только внутри этого класса. К нему нельзя получить доступ извне даже из класса, который его наследует. Чтобы сделать атрибут закрытым, мы должны добавить два символа подчеркивания в качестве префикса имени атрибута.

Изменение имени

Если вы поставите перед именем атрибута двойное подчеркивание (__) следующим образом:

__атрибут

Python автоматически изменит имя атрибута __ на:

_класс__атрибут

Делая это, вы не можете получить доступ к __attribute напрямую извне класса, например:

instance.__атрибут

Однако вы по-прежнему можете получить к нему доступ, используя имя _class__attribute:

instance._class__attribute

● Сеттер и геттер

Сеттеры и геттеры — это два метода, используемые для извлечения и заполнения данных в объекты. В инкапсуляции данные могут быть обернуты модификаторами private, чтобы к ним нельзя было получить доступ напрямую извне класса. Таким образом, методы установки и получения помогут нам получить доступ к данным. Метод создания методов установки и получения такой же, как и создание методов в целом.

Рассмотрим следующий пример:

class User {
 private String username;
 private String password;
   // setter method
   public void setUsername(String username){
     this.username = username;
   }
   public void setPassword(String password){
     this.password = password;
   }
   // getter method
   public String getUsername(){
     return this.username;
   }
   public String getPassword(){
     return this.password;
   }
 }

Методы установки и получения должны иметь общедоступный модификатор, поскольку доступ к этим методам будет осуществляться извне класса. Разница между методами установки и получения заключается в возвращаемом значении, параметрах и содержимом метода. Метод установки не имеет возвращаемого значения. Потому что задача только залить данные в атрибуты. В то время как метод получения имеет возвращаемое значение в соответствии с типом данных, которые необходимо получить.

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

Класс или объект могут быть связаны с другими классами. Одной из форм отношений является наследование. Эти отношения подобны семейным отношениям между родителями и детьми.

У класса может быть один или несколько потомков или дочерних классов. Дочерний класс наследует свойства и методы материнского класса.

При наследовании суперкласс может передавать свои свойства каждому подклассу, но не все свойства, которыми обладает суперкласс, могут быть унаследованы подклассом.

Подсказки разрешений, которые могут быть унаследованы от суперкласса к подклассу, защищены и общедоступны, в то время как частные не будут переданы подклассу.

Создать родительский класс

class Person:
 def __init__(self, fname, lname):
 self.firstname = fname
 self.lastname = lname
 
 def printname(self):
 print(self.firstname, self.lastname)
 
 #Use the Person class to create an object, and then execute the printname method:
 
 x = Person("John", "Doe")
 x.printname()

Создать дочерний класс

class Student(Person):
 pass

Теперь класс Student имеет те же свойства и методы, что и класс Person.

x = Student("Mike", "Olsen")
x.printname()

● Метод переопределения и перегрузки (полиморфизм)

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

В основном это используется в тех случаях, когда метод, унаследованный от родительского класса, не подходит для дочернего класса. Этот процесс повторной реализации метода в дочернем классе известен как Переопределение метода. Вот пример, демонстрирующий полиморфизм с наследованием:

Переопределение метода — это воссоздание существующего метода в суперклассе в подклассе или дочернем классе. Этот метод используется для того, чтобы подкласс имел более конкретную функцию.

class Parent():
 
 # Constructor
 def __init__(self):
   self.value = "Inside Parent"
 
 # Parent's show method
 def show(self):
   print(self.value)
 
 # Defining child class
 class Child(Parent):
 
 # Constructor
 def __init__(self):
   self.value = "Inside Child"
 
 # Child's show method
 def show(self):
   print(self.value)
 
 
 # Driver's code
 obj1 = Parent()
 obj2 = Child()
 
 obj1.show()
 obj2.show()

Перегрузка — это метод, который может создать в классе два или более метода с одинаковым именем, но типы и количество аргументов должны отличаться друг от друга.

● Абстрактный класс

Класс называется абстрактным классом, если он содержит один или несколько абстрактных методов. Абстрактный метод — это метод, который объявлен, но не содержит реализации. Абстрактные классы не могут быть созданы, и его абстрактные методы должны быть реализованы его подклассами.

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

from abc import ABC, abstractmethod
 
 class Polygon(ABC):
 
 @abstractmethod
 def noofsides(self):
   pass
 
 class Triangle(Polygon):
 
 # overriding abstract method
 def noofsides(self):
   print("I have 3 sides")
 
 class Pentagon(Polygon):
 
 # overriding abstract method
 def noofsides(self):
   print("I have 5 sides")
   
 class Hexagon(Polygon):
 
 # overriding abstract method
 def noofsides(self):
   print("I have 6 sides")
 
 class Quadrilateral(Polygon):
 
 # overriding abstract method
 def noofsides(self):
   print("I have 4 sides")
 
 # Driver code
 R = Triangle()
 R.noofsides()
 
 K = Quadrilateral()
 K.noofsides()
 
 R = Pentagon()
 R.noofsides()
 
 K = Hexagon()
 K.noofsides()

//result
I have 3 sides
I have 4 sides
I have 5 sides
I have 6 sides

● Класс интерфейса

В объектно-ориентированных языках, таких как Python, интерфейс представляет собой набор сигнатур методов, которые должны предоставляться реализующим классом. Реализация интерфейса — это способ написания организованного кода и достижения абстракции.

Пакет zope.interface предоставляет реализацию «объектных интерфейсов» для Python. Он поддерживается проектом Zope Toolkit. Пакет напрямую экспортирует два объекта: «Интерфейс» и «Атрибут». Он также экспортирует несколько вспомогательных методов. Он направлен на обеспечение более строгой семантики и более качественных сообщений об ошибках, чем встроенный в Python модуль abc.

import zope.interface
 
class MyInterface(zope.interface.Interface):
  x = zope.interface.Attribute("foo")
  def method1(self, x):
    pass
  def method2(self):
    pass

print(type(MyInterface))
print(MyInterface.__module__)
print(MyInterface.__name__)

# get attribute
x = MyInterface['x']
print(x)
print(type(x))

Реализация интерфейса

Интерфейс действует как схема для разработки классов, поэтому интерфейсы реализуются с помощью декоратора implementer в классе. Если класс реализует интерфейс, то экземпляры класса предоставляют интерфейс. Объекты могут напрямую предоставлять интерфейсы в дополнение к тому, что реализуют их классы.

class MyInterface(zope.interface.Interface):
 x = zope.interface.Attribute("foo")
 def method1(self, x):
   pass
 def method2(self):
   pass
 
@zope.interface.implementer(MyInterface)
class MyClass:
 def method1(self, x):
   return x**2
 def method2(self):
   return "foo"

Мы объявили, что MyClass реализует MyInterface. Это означает, что экземпляры MyClass предоставляют MyInterface.

● Статический метод

В отличие от методов экземпляра, статические методы не привязаны к объекту. Другими словами, статические методы не могут получить доступ и изменить состояние объекта.

Кроме того, Python не передает неявно параметр cls (или параметр self) статическим методам. Следовательно, статические методы не могут получить доступ и изменить состояние класса.

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

Чтобы определить статический метод, вы используете декоратор @staticmethod:

class className:
 @staticmethod
 def static_method_name(param_list):
   pass

Чтобы вызвать статический метод, вы используете этот синтаксис:

className.static_method_name()

● Волшебный метод

Магические методы в Python — это специальные методы, имена которых начинаются и заканчиваются двойным подчеркиванием. Волшебные методы не предназначены для прямого вызова, но они будут вызываться системой внутри в определенное время.

__str__

Метод __str__() будет вызываться, когда экземпляр соответствующего класса преобразуется в строку или когда он используется в качестве параметра функции print().

class Segitiga:
 
 def __init__(self, a, t):
   self.alas = a
   self.tinggi = t
 
 def __str__(self):
   luas = 0.5 * self.alas * self.tinggi
   return f'segitiga (alas={self.alas} tinggi={self.tinggi} luas={luas})'
 
# create an instance
a = Segitiga(10, 10)
b = Segitiga(20, 10)
print(a)
print(b)
segitiga (alas=10 tinggi=10 luas=50.0)
segitiga (alas=20 tinggi=10 luas=100.0)

● Перегрузка оператора

Перегрузка операторов — это метод, при котором мы будем управлять или определять поведение класса и то, как он будет взаимодействовать с различными операторами.

Чтобы увидеть перегрузку оператора Python в действии, запустите терминал Python и выполните следующие команды:

class Angka:
 def __init__(self, angka):
   self.angka = angka
 
 def __add__(self, objek):
   return self.angka + objek.angka

x1 = Angka(10)
x2 = Angka(20)
 
print(x1 + x2)

// result
30

● Супер()

Python также имеет функцию super(), которая заставляет дочерний класс наследовать все методы и свойства своего родителя:

class Student(Person):
 def __init__(self, fname, lname):
 super().__init__(fname, lname)

При использовании функции super() вам не нужно использовать имя родительского элемента, он автоматически унаследует методы и свойства от своего родителя.

Добавить свойства

class Student(Person):
 def __init__(self, fname, lname):
   super().__init__(fname, lname)
   self.graduationyear = 2019

В приведенном ниже примере 2019 год должен быть переменной и передаваться в класс Student при создании объектов Student.

● Множественное наследование

В языке программирования Python класс может наследовать более одного родительского класса. Возможность наследования более чем одного класса называется множественным наследованием.

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

class Parent1:
 pass
 
class Parent2:
 pass
 
class Turunan(Induk1, Induk2):
 pass

В приведенном выше примере класс Child становится «потомком» класса Parent1, а также класса Parent2.

● Порядок разрешения метода

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

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

Специально для множественного наследования порядок родительских классов слева направо. Таким образом, первый производный класс — это самый левый класс, затем правый и так далее.

Порядок, в котором этот метод называется порядком разрешения метода (MRO).