Наследование и полиморфизм в Python
1. Введение
Наследствие и полиморфизм - очень важное понятие в Python. Вы должны понять эту тему.
Перед изучением "Наследование вPython", удостоверьтесь, что у вас уже есть представление о "Классеиобъекте", если нет, давайте изучим:
Статья основана на:
Python 3.x
2. Наследование в Python
Python позволяет вам создать расширенный класс из одного или многих других классов. Этот класс называется производный класс (derived class) или просто подкласс.
Подкласс унаследует атрибуты, методы, и другие члены из родительского класса. Он так же может переопределять (override) методы родительского класса. Если подкласс не определяет свой конструктор, он унаследует конструктор родительского класса по умолчанию.
Подкласс унаследует атрибуты, методы, и другие члены из родительского класса. Он так же может переопределять (override) методы родительского класса. Если подкласс не определяет свой конструктор, он унаследует конструктор родительского класса по умолчанию.
В отличие от Java, CSharp и некоторых других языков, Python допускает множественное наследование. Класс может быть расширен из одного или нескольких родительских классов.
Нам нужно несколько классов для примера.
- Animal (Животное): Класс имитирует животное.
- Duck (Утка): Класс имитирует утку, это подкласс Животного.
- Cat (Кот): Класс имитирует кота, это подкласс Животного.
- Mouse (Мышь): Класс имитирует мышь, это подкласс Животного.
В Python, конструктор (constructor) используется для создания объекта и прикрепляет значение атрибутам (attribute).
Конструктор подклассов всегда вызывается конструктором родительского класса, чтобы инициализировать значение для атрибутов родительского класса, затем он прикрепляет значение этим атрибутам.
Конструктор подклассов всегда вызывается конструктором родительского класса, чтобы инициализировать значение для атрибутов родительского класса, затем он прикрепляет значение этим атрибутам.
Например:
animal.py
class Animal :
# Constructor
def __init__(self, name):
# Класс Animal имеет 1 атрибут (attribute): 'name'.
self.name= name
# Метод (method):
def showInfo(self):
print ("I'm " + self.name)
# Метод (method):
def move(self):
print ("moving ...")
Cat является подклассом, унаследованным от класса Animal, он тоже имеет атрибуты (attribute) этого класса.
cat.py
from animal import Animal
# Клас Cat расширен (extends) из класса Animal.
class Cat (Animal):
def __init__(self, name, age, height):
# Вызывается constructor родительского класса (Animal)
# чтобы прикрепить значение к атрибуту 'name' родительского класса.
super().__init__(name)
self.age = age
self.height = height
# Переопределить (override) метод с одинаковым названием родительского класса.
def showInfo(self):
print ("I'm " + self.name)
print (" age " + str(self.age))
print (" height " + str(self.height))
catTest.py
from cat import Cat
tom = Cat("Tom", 3, 20)
print ("Call move() method")
tom.move()
print ("\n")
print ("Call showInfo() method")
tom.showInfo()
Результат запуска модуля catTest:
Call move() method
moving ...
Call showInfo() method
I'm Tom
age 3
height 20
Что случится, когда вы создаёте объект конструктором (constructor)? Как он вызовет коструктор родительского класса? Смотрите иллюстрацию ниже:
С иллюстрации выше вы видите, что конструктор (constructor) родителькского класса вызывается в конструкторе подкласса, она присвоит значения атрибутам (attribute) родительского класса, затем и атрибутам подкласса.
3. Переопределить метод
По умолчанию, подкласс унаследует методы из родительского класса, но подкласс может переопределять (override) методы родительского класса.
mouse.py
from animal import Animal
# Класс Mouse расширен (extends) из класса Animal.
class Mouse (Animal):
def __init__(self, name, age, height):
# Вызывается Constructor родительского класса (Animal)
# чтобы прикрепить значение к атрибуту 'name' родительского класса.
super().__init__(name)
self.age = age
self.height = height
# Переопределить (override) метод с одинаковым названием родительского класса.
def showInfo(self):
# Вызвать метод родительского класса.
super().showInfo()
print (" age " + str(self.age))
print (" height " + str(self.height))
# Переопределить (override) метод с одинаковым названием родительского класса.
def move(self):
print ("Mouse moving ...")
Test
mouseTest.py
from mouse import Mouse
jerry = Mouse("Jerry", 3, 5)
print ("Call move() method")
jerry.move()
print ("\n")
print ("Call showInfo() method")
jerry.showInfo()
Output:
Call move() method
Mouse moving ...
Call showInfo() method
I'm Jerry
age 3
height 5
4. Абстрактный метод
Понятие абстракного метода (abstract method) или абстракного класса (abstract class) имеется в таких языках как Java, C#. Но не полностью определяется в Python. Все же у нас есть способ определить его.
Класс, называется абстрактным (abstract), определяет абстрактные методы и подкласс должен переопределять (override) эти методы, если хочет их использовать. Абстрактные методы всегда вызывают исключение NotImplementedError.
abstractExample.py
# Абстрактный класс (Abstract class).
class AbstractDocument :
def __init__(self, name):
self.name = name
# Метод невозможно использовать, так как всегда выбрасывает ошибку.
def show(self):
raise NotImplementedError("Subclass must implement abstract method")
class PDF(AbstractDocument):
# Переопределить метод родительского класса
def show(self):
print ("Show PDF document:", self.name)
class Word(AbstractDocument):
def show(self):
print ("Show Word document:", self.name)
# ----------------------------------------------------------
documents = [ PDF("Python tutorial"),
Word("Java IO Tutorial"),
PDF("Python Date & Time Tutorial") ]
for doc in documents :
doc.show()
Output:
Show PDF document: Python tutorial
Show Word document: Java IO Tutorial
Show PDF document: Python Date & Time Tutorial
В приведенном выше примере демонстрируется полиморфизм (Polymorphism) в Python. Объект Document (документ) может быть представлен в различных формах (PDF, Word, Excel, ...).
Другой пример иллюстрирует полиморфизм: когда я говорю об азиатском человеке, это довольно абстрактно, он может быть японцем, вьетнамцем или индийцем. Однако, у них у всеъ есть особенности азиатских людей.
5. Множественное наследование
Python позволяет множественное наследование, что означает, что вы можете создать расширенный класс из двух или более других классов. Родительские классы могут иметь одинаковые атрибуты (attribute) или методы .... Подкласс будет приоритетно наследовать атрибуты, методы, ... первого класса в списке наследования.
multipleInheritanceExample.py
class Horse:
maxHeight = 200; # centimeter
def __init__(self, name, horsehair):
self.name = name
self.horsehair = horsehair
def run(self):
print ("Horse run")
def showName(self):
print ("Name: (House's method): ", self.name)
def showInfo(self):
print ("Horse Info")
class Donkey:
def __init__(self, name, weight):
self.name = name
self.weight = weight
def run(self):
print ("Donkey run")
def showName(self):
print ("Name: (Donkey's method): ", self.name)
def showInfo(self):
print ("Donkey Info")
# Класс Mule унаследован от Horse и Donkey.
class Mule(Horse, Donkey):
def __init__(self, name, hair, weight):
Horse.__init__(self, name, hair)
Donkey.__init__(self, name, weight)
def run(self):
print ("Mule run")
def showInfo(self):
print ("-- Call Mule.showInfo: --")
Horse.showInfo(self)
Donkey.showInfo(self)
# ---- Test ------------------------------------
# Переменная 'maxHeight', унаследована от класса Horse.
print ("Max height ", Mule.maxHeight)
mule = Mule("Mule", 20, 1000)
mule.run()
mule.showName()
mule.showInfo()
Output:
Max height 200
Mule run
Name: (House's method): Mule
-- Call Mule.showInfo: --
Horse Info
Donkey Info
Метод mro()
Метод mro() позволяет просматривать список родительских классов определенного класса. Давайте посмотрим на следующий пример:
mroExample.py
class X: pass
class Y: pass
class Z: pass
class A(X,Y): pass
class B(Y,Z): pass
class M(B,A,Z): pass
# Output:
# [<class '__main__.M'>, <class '__main__.B'>,
# <class '__main__.A'>, <class '__main__.X'>,
# <class '__main__.Y'>, <class '__main__.Z'>,
# <class 'object'>]
print(M.mro())
Примечание: В Python команда pass (pass statement) подобна команде null (или пустой), она ничего не делает, если у класса или метода нет содержимого, вам по-прежнему нужна хотя бы одна команда, давайте использовать pass.
6. Функция issubclass и isinstance
Python имеет две полезные функции:
- isinstance
- issubclass
isinstance
Функция isinstance помогает вам проверить, является ли "что-то" объектом определенного класса или нет.
issubclass
Функция issubclass проверяет, является ли этот класс потомком другого класса или нет.
isinstancesubclass.py
class A: pass
class B(A): pass
# True
print ("isinstance('abc', object): ",isinstance('abc', object))
# True
print ("isinstance(123, object): ",isinstance(123, object))
b = B()
a = A()
# True
print ("isinstance(b, A): ", isinstance(b, A) )
print ("isinstance(b, B): ", isinstance(b, B) )
# False
print ("isinstance(a, B): ", isinstance(a, B) )
# B is subclass of A? ==> True
print ("issubclass(B, A): ", issubclass(B, A) )
# A is subclass of B? ==> False
print ("issubclass(A, B): ", issubclass(A, B) )
Output:
isinstance('abc', object): True
isinstance(123, object): True
b = B()
a = A()
isinstance(b, A): True
isinstance(b, B): True
isinstance(a, B): False
isinstance(B, A): True
isinstance(A, B): False
7. Полиморфизм с функцией
Здесь я создаю два класса, English и French. У обоих классов есть метод greeting(). Оба создают разные приветствия. Создайте два соответствующих объекта из двух классов выше и вызовите действия этих двух объектов в одной функции (функция intro).
people.py
class English:
def greeting(self):
print ("Hello")
class French:
def greeting(self):
print ("Bonjour")
def intro(language):
language.greeting()
flora = English()
aalase = French()
intro(flora)
intro(aalase)
Запуск примера:
Hello
Bonjour
Pуководства Python
- Документация по поиску Python
- Ветвление операторы в Python
- Руководство Python Function
- Класс и объект в Python
- Наследование и полиморфизм в Python
- Руководство Python Dictionary
- Руководство Python Lists
- Руководство Python Tuples
- Руководство Python Date Time
- Подключиться к базе данных MySQL на Python с помощью PyMySQL
- Руководство по исключению Python
- Руководство Python String
- Введение в Python
- Установить Python в Windows
- Установите Python в Ubuntu
- Установите PyDev для Eclipse
- Соглашения и версии грамматики в Python
- Руководство Python для начинающих
- Петли в Python
Show More