Рубрики
Без рубрики

Введение в классы Python – наследование, инкапсуляция и полиморфизм

Эта статья продолжается от введения классов – часть, где мы объяснили, какие классы, их компоненты, и почему мы их используем. Мы также смотрели на некоторые уникальные характеристики классов, которые помогают нам в создании чистого кода. Если вы еще не читали часть одного и нового в классы, я предлагаю прочитать, что введение … Введение в классы Python – наследование, инкапсуляция и полиморфизм Подробнее »

Автор оригинала: David Yeoman.

Эта статья продолжается от введения классов – часть, где мы объяснили, какие классы, их компоненты, и почему мы их используем. Мы также смотрели на некоторые уникальные характеристики классов, которые помогают нам в создании чистого кода. Если вы еще не читали часть одного и нового в классы, я предложил прочитать это введение первым.

*** Учебное пособие Часть 1: Введение в классы Python ***

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

Наследование – Что это и зачем использовать это?

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

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

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

  • Мы измеряем может содержание по объему в миллилитрах или мл;
  • Мы взвешиваем мясо в килограммах или кг.
  • Могут иметь длительный срок годности; Мясо имеет краткое использование по дате.
  • Мы могли бы попытаться добавить все возможные вариации товара в классе, но это несколько громоздко.
  • Как насчет того, чтобы держать эти общие предметы, обладающие всеми продуктами в классе Снабжать Как родительский класс, и создайте детские классы для мяса и банки соответственно, которые удовлетворяют конкретным потребностям этих предметов?

Вот код.

class Stock:
    category = 'Groceries'

    def __init__(self, stock_code, description, buy_price, mark_up):
        self.code = stock_code
        self.desc = description
        self.buy = buy_price
        self.margin = mark_up

    def sell_price(self):
        print('Retail price = $', round(self.buy * self.margin, 2))

    def sale(self, discount):
        print('The discounted price of {} is $'.format(C298.desc),
              round(self.buy * self.margin * (1- discount), 2))

class Canned(Stock):
    category = 'Cans'

    def __init__(self, stock_code, description, buy_price, mark_up, volume, manuf):
        Stock.__init__(self, stock_code, description, buy_price, mark_up)
        self.volume = volume
        self.manuf = manuf

    def multi_buy(self):
        print('Buy two {} of {} {} {} and get one free. Pay only ${}'.format(self.category, self.manuf, self.volume, self.desc, round(self.buy * self.margin, 2)))

C298 = Canned('C298', 'Chicken Soup', 0.75, 1.553, '400 mls', 'Campbells')

C298.sale(.15)

C298.multi_buy()

Давайте пройдемся через это. Код класса акций такой же, как и в предыдущей статье. Дополнение из «Классных консервированных (акций):« линия кода. Мы создали новый класс, называемый консервированным, используя тот же синтаксис, поскольку мы сделали с накладки; Тем не менее, мы назвали запас как родитель, указанные, включая его в скобки.

class Canned(Stock):
    category = 'Cans'

На следующей строке мы создали категорию классов «Банки» Тогда мы использовали __init__ Функция как до того, чтобы определить параметры. Большинство параметров такие же, как в Сток класс, но мы добавили еще два, «Том» и «Мануф» Отказ Это параметры, специфичные для консервированного класса. Следующая строка использует Запас .__ init__ ссылаться на Родитель классы параметров. Эта линия – это то, где волшебство происходит с наследством. Позвонив классу Консервированные (Сток) И вставьте эту строку, теперь у вас есть связь между двумя классами, что позволяет передавать атрибуты и методы.

    def __init__(self, stock_code, description, buy_price, mark_up, volume, manuf):
        Stock.__init__(self, stock_code, description, buy_price, mark_up)

Мы передаем новые параметры «Том» и «Мануф» к Self.Volume. и Self.manuf атрибуты, то мы создали новый метод для Консервированный класс. Этот новый метод называется multi_buy () И при активации печатает этикетку, позволяющую покупателям покупать две банки продукта по цене одного.

        self.volume = volume
        self.manuf = manuf

    def multi_buy(self):
        print('Buy two {} of {} {} {} and get one free. Pay only ${}'.format(self.category, self.manuf, self.volume, self.desc, round(self.buy * self.margin, 2)))

Следующая строка кода создает или «Инстанции» объект из класса Консервированный Использование фондового кода C298 для создания банки куриного супа путем передачи параметров в требуемом порядке.

C298 = Canned('C298', 'Chicken Soup', 0.75, 1.553, '400 mls', 'Campbells')

C298.sale(.15)

C298.multi_buy()

На следующей строке мы называем метод Продажа () Для нашего объекта и пройти скидка 15%. Обратите внимание, что Продажа () Метод относится к Запас () Класс, а не Консервированный Класс, но это доступно из-за потока наследования между Ребенок и Родитель Отказ Затем мы называем новый метод, который мы определили в Консервированный Класс называется multi_buy () Отказ Вот результат, когда мы запустим код.

# Result

The discounted price of Chicken Soup is $ 0.99
Buy two Cans of Campbells 400 mls Chicken Soup and get one free. Pay only $1.16

Как видите, у нас есть возможность использовать Продажа () Метод от родительского класса Запас () или multi_buy () Метод от детского класса, Консервированный Отказ Здесь лежит часть магии наследования. Мы можем создать столько детских классов от Сток Как мы желаем. Давайте создадим класс для мяса. Как мы уже говорили, мы измеряем мясо по весу и необходимость устанавливают использование по дате, как это особенно скоропортящиеся продукты питания.

class Meat(Stock):
    category = 'Meat'

    def __init__(self, stock_code, description, buy_price, mark_up, weight, use_by):
        self.kilo = weight
        self.expiry = use_by
        Stock.__init__(self, stock_code, description, buy_price, mark_up)

    def Label(self):
        print(self.desc, '\nWeight: ', self.kilo, 'kgs', '\nExpiry: ', self.expiry)
        self.sell_price()

    def Expiring(self, discount):
        print('Price reduced for quick sale: ${}'.format(round(self.buy * self.margin * (1 - discount), 2)))

Этот код следует за всеми шагами, которые мы проходили на Консервированный класс. Мы создали класс Мясо (сток) , что означает, что это ребенок Сток класс. Мы дали это категорию Мясо Затем использовал __init__ Функция для определения параметров, которые мы требуем. Два новых, которые отличаются от Сток класс ” Вес ‘и’ использовать в ‘. Затем мы передаем эти параметры для Self.kilo и self.expiry атрибуты. Наконец, мы используем Запас .__ init__ Команда для создания ссылки на родительские параметры.

В Мясо () Мы определили два метода, специфичными для Мясо () класс. Первый – это метод для печати этикетки, который мы можем разместить снаружи упаковки мяса. Второе – это метод дисконтирования, который уменьшит мясо в цене, так как он приближается к дате истечения срока действия; Нам просто нужно пройти скидку на метод.

Теперь мы создадим или мститель, объект из Мясо () Класс для какого-то кирно стейка мы хотим продать в нашем магазине, и мы назовем два новых метода, Этикетка () и Срок действия () Отказ Тогда мы также позвоним multi_buy () Метод для куриного супа, чтобы доказать, что два объекта стейка в килки и куриный суп, созданные как детские классы родительского класса Запас () , может с радостью сосуществовать.

C401 = Meat('C401', 'Sirloin Steak', 4.16, 1.654, .324, '15 June 2021')

C298 = Canned('C298', 'Chicken Soup', 0.75, 1.553, '400 mls', 'Campbells')

C401.Label()
print()
C401.Expiring(.35)
print()
C298.multi_buy()

# Result

Sirloin Steak 
Weight:  0.324 kgs 
Expiry:  15 June 2021
Retail price = $ 6.88

Price reduced for quick sale: $4.47

Buy two Cans of Campbells 400 mls Chicken Soup and get one free. Pay only $1.16

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

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

Инкапсуляция – это способность, в Объектно-ориентированное-программирование , чтобы ограничить модификацию переменных, атрибутов или методов в классе. Мы будем использовать начальную Сток класс в качестве примера, чтобы продемонстрировать это. Давайте предположим, что мы не хотим разрешить « » Self.Margin «Атрибут быть легко измененным. Мы можем сделать это, используя один или двойной подчеркивание перед именем атрибута.

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

class Stock:
    category = 'Groceries'

    def __init__(self, stock_code, description, buy_price, mark_up):
        self.code = stock_code
        self.desc = description
        self.buy = buy_price
        self.margin = mark_up

    def sell_price(self):
        print('Retail price = $', round(self.buy * self.margin, 2))

    def sale(self, discount):
        print('The discounted price of {} is $'.format(C298.desc),
              round(self.buy * self.margin * (1 - discount), 2))

C298 = Stock('C298', 'Chicken Soup', 0.75, 1.553)

C298.sell_price()

C298.margin = 1.2

C298.sell_price()

# Result

Retail price = $ 1.16
Retail price = $ 0.9

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

class Stock:
    category = 'Groceries'

    def __init__(self, stock_code, description, buy_price, mark_up):
        self.code = stock_code
        self.desc = description
        self.buy = buy_price
        self.__margin = mark_up

    def sell_price(self):
        print('Retail price = $', round(self.buy * self.__margin, 2))

    def sale(self, discount):
        print('The discounted price of {} is $'.format(C298.desc),
              round(self.buy * self.__margin * (1 - discount), 2))

C298 = Stock('C298', 'Chicken Soup', 0.75, 1.553)

C298.sell_price()

C298.margin = 1.2

C298.sell_price()

# Result

Retail price = $ 1.16
Retail price = $ 1.16

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

class Stock:
    category = 'Groceries'

    def __init__(self, stock_code, description, buy_price, mark_up):
        self.code = stock_code
        self.desc = description
        self.buy = buy_price
        self.__margin = mark_up

    def sell_price(self):
        print('Retail price = $', round(self.buy * self.__margin, 2))

    def sale(self, discount):
        print('The discounted price of {} is $'.format(C298.desc),
              round(self.buy * self.__margin * (1 - discount), 2))

    def setMargin(self, new_margin):
        self.__margin = new_margin

C298 = Stock('C298', 'Chicken Soup', 0.75, 1.553)

C298.sell_price()

C298.margin = 1.2

C298.sell_price()

C298.setMargin(1.426)

C298.sell_price()

# Result

Retail price = $ 1.16
Retail price = $ 1.16
Retail price = $ 1.07

С новым SetMargin () Способ, мы теперь создали дискретные средства, с помощью которых мы можем изменить нашу маржу продаж. В вышеуказанном выше коде мы использовали новый способ изменить запас от 1,553 до 1,426, что привело к снижению цены на продажу в размере 1,07 долл. США.

Полиморфизм

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

Мы создадим подобное Этикетка () Метод в нашем Консервированный класс, который мы использовали в Мясо класс, чтобы показать это в действии. Выход каждого метода будет другим, но название метода будет одинаковым. Тогда мы создадим функцию, которая позвонит методу Этикетка () Использование фондовых кодов у нас для мяса и Суп Отказ Как вы увидите, полиморфизм позволит обе функции работать независимо от Печать из правильных меток.

class Stock:
    category = 'Groceries'

    …. # Code truncated for brevity

class Canned(Stock):
    category = 'Cans'

    def __init__(self, stock_code, description, buy_price, mark_up, volume, manuf):
        self.volume = volume
        self.manuf = manuf
        Stock.__init__(self, stock_code, description, buy_price, mark_up)

    def Label(self):
        print(self.desc, '\nVolume: ', self.volume)
        self.sell_price()

C298 = Canned('C298', 'Chicken Soup', 0.75, 1.553, '400 mls', 'Campbells')

class Meat(Stock):
    category = 'Meat'

    def __init__(self, stock_code, description, buy_price, mark_up, weight, use_by):
        self.kilo = weight
        self.expiry = use_by
        Stock.__init__(self, stock_code, description, buy_price, mark_up)

    def Label(self):
        print(self.desc, '\nWeight: ', self.kilo, 'kgs', '\nExpiry: ', self.expiry)
        self.sell_price()

C401 = Meat('C401', 'Sirloin Steak', 4.16, 1.654, .324, '15 June 2021')

def label_print(*args):
    for elem in args:
        elem.Label()
        print()

label_print(C401, C298)

# Result
Sirloin Steak 
Weight:  0.324 kgs 
Expiry:  15 June 2021
Retail price = $ 6.88

Chicken Soup 
Volume:  400 mls
Retail price = $ 1.16

Как вы можете видеть в предыдущем коде, Def Metal (Self): Часть метода идентична в каждом классе, но данные, которые будут напечатаны на этикетку, отличаются.

Затем мы создали функцию вне всех трех классов, называемых label_print () , и нам позволили пройти несколько аргументов к нему, используя * args синтаксис в скобках. Тогда мы просто повторяем каждый аргумент, однако многие могут быть, и позвонить в Этикетка () Метод в применимом классе, к которому принадлежит этот аргумент. Результат мы напечатано Этикетки для каждого объекта, созданного из двух разных детских классов.

Резюме

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

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

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

Вы можете прочитать часть одной из этой статьи здесь:

*** Учебное пособие Часть 1: Введение в классы Python ***

Я доверяю, эти две статьи были полезны для понимания классов в Python. Спасибо за чтение.

Оригинал: “https://blog.finxter.com/an-introduction-to-python-classes-inheritance-encapsulation-and-polymorphism/”