ООП. Абстрактный класс. Декомпозиция программы.

Содержание

  • Абстрактные классы
  • Декомпозиция программы на модули
  • Задачи:
    • Задача 1:
    • Задача 2:
    • Задача 3* ДНК

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

В python существует стандартная библиотека abc, добавляющая в язык абстрактные базовые классы (АБК). АБК позволяют определить класс, указав при этом, какие методы или свойства обязательно переопределить в классах-наследниках.

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

from abc import ABC, abstractmethod
class ChessPiece(ABC):
    # общий метод, который будут использовать все наследники этого класса
    def draw(self):
        print("Drew a chess piece")
    # абстрактный метод, который будет необходимо переопределять для каждого подкласса
    @abstractmethod
    def move(self):
        pass
a = ChessPiece() # Если мы попытаемся инстанциировать данный класс, логично получим ошибку.
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-91-1f9727e5cc03> in <module>()
----> 1 a = ChessPiece() # Если мы попытаемся инстанциировать данный класс, логично получим ошибку.
TypeError: Can't instantiate abstract class ChessPiece with abstract methods move

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

class Queen(ChessPiece):
    def move(self):
        print("Moved Queen to e2e4")
# Мы можем создать экземпляр класса
q = Queen()
# И нам доступны все методы класса
q.draw()
q.move()
Drew a chess piece
Moved Queen to e2e4

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

from abc import ABC, abstractmethod
class Basic(ABC):
    @abstractmethod
    def hello(self):
        print("Hello from Basic class")
class Advanced(Basic):
    def hello(self):
        super().hello()
        print("Enriched functionality")
a = Advanced()
a.hello()
Hello from Basic class
Enriched functionality

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

подробности можно найти в документации: https://docs.python.org/3/library/abc.html

Модули и пакеты в Python – это прекрасные инструменты для управления сложностью в программном проекте.

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

Создадим ещё один модуль worker.py, который будет использовать функции из simplemath.py. Если мы хотим импортировать все функции, то оператор import для нас отлично подойдет. Это будет выглядеть так.

# представим, что эта ячейка - текстовый редактор, который мы сохраним под именем simplemath.py
def add(a, b):
    return a + b
def sub(a, b):
    return a - b
def mul(a, b):
    return a * b
def div(a, b):
    return a / b
# представим, что эта ячейка - текстовый редактор, который мы сохраним под именем simplemath.py
#import simplemath
#from simplemath inpord add,sub,mul,div
#print(simplemath.add(1, 2)) # = 3
#print(simplemath.sub(1, 2)) # = -1
#print(simplemath.
mul(1, 2)) # = 2 #print(simplemath.div(1, 2)) # = 0.5

Задача 1:

В файле вам даны 3 класса A, B, C, имеющие сходный (но не одинаковый) интерфейс. Вам необходимо создать абстрактный базовый класс Base и построить корректную схему наследования. При выполнении следует избегать дублирования кода, и стараться следовать SOLID принципам ООП.

Задача 2:

В файле вам дана программа. Необходимо провести её рефакторинг.

Для работы программы необходима библиотека PyGame. В открывшемся окне программы доступны следующие команды управления:

  • <F1>  — показать справку по командам
  • <R>  — рестарт
  • <P>  — пауза, снять/поставить
  • <num->  — увеличить количество точек «сглаживания»
  • <num+>  — уменьшить количество точек «сглаживания»
  • <mouse left>  — добавить «опорную» точку

По умолчанию при старте программы «опорные» точки отсутствуют и программа находится в состоянии паузы (движение кривой выключено). Для добавления точек сделайте несколько кликов левой клавишей мыши в любом месте окна программы. Отрисовка кривой произойдет, когда точек на экране станет больше двух. Нажмите клавишу 

<P>, чтобы включить движение кривой.

Ваша задача:

  1. Изучить документацию к библиотеке pygame и код программы. Понять механизм работы программы (как происходит отрисовка кривой, перерасчет точек сглаживания и другие нюансы реализации программы)
  2. Провести рефакторниг кода, переписать программу в ООП стиле с использованием классов и наследования. Реализовать класс 2-мерных векторов Vec2d . В классе следует определить методы для основных математических операций, необходимых для работы с вектором. Добавить возможность вычислять длину вектора с использованием функции len(a) и метод
    int_pair
    , который возвращает кортеж из двух целых чисел (текущие координаты вектора).

Реализовать класс замкнутых ломаных Polyline с методами отвечающими за добавление в ломаную точки (Vec2d) c её скоростью, пересчёт координат точек (set_points) и отрисовку ломаной (draw_points). Арифметические действия с векторами должны быть реализованы с помощью операторов, а не через вызовы соответствующих методов.

Реализовать класс Knot

(наследник класса Polyline), в котором добавление и пересчёт координат инициируют вызов функции get_knot для расчёта точек кривой по добавляемым «опорным» точкам.

Все классы должны быть самостоятельными и не использовать внешние функции.

Задача 3* ДНК

Реализуйте классы для ДНК (двойная цепочк) и РНК (одинарная цепочка).
Данные структуры данных должны поддерживать следующие возможности:

1. Создавать структуру из строк. Обратите внимание, что в ДНК встречаются только азотистые основания ATGC, а в РНК (AUGC) поэтому если во входной строке содержались другие символы, необходимо поднимать ошибку (Exception). 2. Поддерживают индексацию. РНК по индексу возвращает i-ое азотистое основание, ДНК — пару азотистых оснований (соответствующие первой и второй цепочке) 3.

РНК может возвращать комплиментарную ДНК (каждому азотистому основанию из РНК соответсвует соответсвующее основание для первой цепочки ДНК: A → T, U → A, G → C, C → G. Вторая цепочка ДНК строится комплиментарной первой строчке ДНК: A → T, T → A, G → C, C → G) 4. РНК, как и ДНК, могут складываться путем склеивания («AUUGAACUA» + «CGGAAA» = «AUUGAACUACGGAAA»). У ДНК склеиваются соответствующие цепочки ([«ACG», «TGC»] + [«TTTAAT», «AAATTA»] = [«ACGTTTAAT», «TGCAAATTA»]) 5. РНК могут перемножаться друг с другом: каждое азотистое основание результирующей РНК получается случайным выбором одного из двух соответсвующих родительских азотистых оснований. Если одна из цепочек длиннее другой, то перемножение происходит с начала, когда одна из цепочек закончится оставшийся хвост другой переносится без изменений. 6. ДНК могут перемножаться друг с другом: ПЕРВЫЕ цепочки каждой из ДНК перемножаются по такому же приницпу, как перемножаются РНК выше.
Вторая цепочка результирующей ДНК строится как комплиментарная первой 7. Цепочки РНК и первую и вторую у ДНК можно проверять на равенство 8. Оба класса должны давать осмысленный вывод как при print, так и просто при вызове в ячейке |
Обдумайте и создайте необходимые и, возможно, вспомогательные классы, настройте наследование, если требуется. Полученная структура должна быть адекватной и удобной, готовой к простому расширению функционала, если потребуется

Абстрактные классы. Курс «ООП в Kotlin»

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

Например, в программе есть различные классы юнитов – пехотинцы, всадники, герои. Их общие свойства и методы можно вынести в один общий класс «юнит». Поскольку в программе не может быть просто юнита, такой класс имеет смысл сделать абстрактным.

В Kotlin абстрактные классы имеют модификатор abstract вместо open, то есть абстрактные классы всегда открыты для наследования, иначе в них не было бы смысла. Сделаем наш класс NumInc абстрактным:

abstract class NumInc(n: Int, s: Int) {
    var number = n
    var step = s
    fun inc() {number += step}
    fun dec() {number -= step}
}

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

val a = NumMult(3,4)
val b: NumInc = NumDouble(2, 2)

Здесь переменная a будет иметь тип дочернего класса, b хоть и связана с объектом дочернего класса, будет иметь тип абстрактного родительского класса. Следующее выражение недопустимо:

val c = NumInc(1, 4)

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

Если класс NumInc определен так, как представлено выше, в дочерних классах мы не можем переопределять его свойства и методы, только добавлять новые. Чтобы иметь возможность переопределения, их по-прежнему надо делать открытыми.

abstract class NumInc(n: Int, s: Int) {
    var number = n
    var step = s
    open fun inc() {number += step}
    open fun dec() {number -= step}
}
class NumDouble(n: Int, s: Int): NumInc(n, s) {
    override fun inc() {
        super. inc()
        super.inc()
    }
}

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

abstract class NumInc(n: Int, s: Int) {
    var number = n
    var step = s
 
    abstract fun inc()
    abstract fun dec()
}
class NumDouble(n: Int, s: Int): NumInc(n, s) {
 
    override fun inc() {
        number += 2 * step
    }
 
    override fun dec() {
        number -= 2 * step
    }
}

В другом дочернем классе реализация функций inc() и dec() может быть совсем другой.

class NumMult(n: Int, s: Int, q: Int): NumInc(n, s) {
    val coefficient = q
 
    override fun inc() {
        number += step * coefficient
    }
 
    override fun dec() {
        number -= step * coefficient
    }
}

Одинаковыми являются лишь параметры (в данном случае их нет) и тип возвращаемого значения. Все это определено в родительском абстрактном классе.

Обратим внимание еще раз. Когда мы делаем методы абстрактного класса просто открытыми или оставляем закрытыми, то можем их не переопределять в дочерних. Хотя при необходимости можем и переопределить. Если метод абстрактный, то не переопределить его нельзя. Это будет ошибкой. Мы обязаны создавать его переопределение в любом дочернем классе.

В чем выгода от этого? Мы могли бы вообще не описывать эти абстрактные методы в абстрактном классе и реализовывать только в дочерних при необходимости. Выгода – в одинаковой сигнатуре дочерних классов. Гарантируется, что у всех них есть что-то общее – одинаковые методы, что позволит выполнять групповую обработку объектов, созданных от разных классов.

В IntelliJ IDEA, когда вы создаете класс и хотите (или это требуется в случае абстрактных) переопределить свойства и методы родительского класса, можно нажать Ctrl + O, появится окно, где следует выбрать то, что вам требуется. IDEA сама сформирует заголовок.

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

abstract class NumInc {
    abstract var number: Int
    abstract var step: Int
    abstract fun inc()
    abstract fun dec()
}

Обратите внимание, что у класса нет собственного конструктора. Пример его дочернего класса:

class NumMult(n: Int, s: Int, q: Int): NumInc() {
    override var number = n
    override var step = s
    val coefficient = q
 
    override fun inc() {
        number += step * coefficient
    }
    override fun dec() {
        number -= step * coefficient
    }
}

Практическая работа:

  1. Проверьте, можно ли в неабстрактном классе определить абстрактный метод. Объясните результат.

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

PDF-версия курса с ответами к практическим работам

Приложение для Android «Kotlin. Курс»


Что такое абстрактный класс? — Определение из WhatIs.com

По

  • Участник TechTarget

Абстрактный класс — это шаблон определения методов и переменных класса (категории объектов), который содержит один или несколько абстрактных методов. Абстрактные классы используются во всех языках объектно-ориентированного программирования (ООП), включая Java (см. Абстрактный класс Java), C++, C# и VB.NET. Объекты или классы могут быть абстрагированы, что означает, что они обобщаются в характеристики, относящиеся к текущей работе программы.

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

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

См. краткое руководство по абстрактным и конкретным классам:

Последнее обновление: июль 2016 г.

Продолжить чтение Об абстрактном классе
  • Семь советов, как стать Java-разработчиком Мастер Zen
  • Обсуждение StackOverflow о разнице между абстрактными классами и конкретными классами
  • Разница между интерфейсом, абстрактным классом и конкретным классом
  • Тест: что вы знаете о работе с Java?
  • Абстракция Java
Углубитесь в разработку и развертывание мобильных устройств
  • экземпляр

    Автор: Эндрю Зола

  • экземпляр

    Автор: Эндрю Зола

  • объект

    Автор: Петр Лошин

  • Среда персистентности MicroStream с открытым исходным кодом

    Автор: Адриан Бриджуотер

SearchAppArchitecture

  • Почему контрактное тестирование может быть необходимо для микросервисов

    Разработчики сталкиваются с многочисленными трудностями, пытаясь выполнить традиционное сквозное интеграционное тестирование микросервисов. Контракт…

  • Растущая роль разработчиков, ориентированных на данные

    Больше, чем когда-либо, растущая зависимость разработчиков от данных, источников данных и пользователей подталкивает разработчиков к пониманию ИТ-покупок …

  • 12 рекомендаций по безопасности API для защиты вашего бизнеса

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

ПоискSoftwareQuality

  • Чтобы безопасность API была успешной, разработчикам нужны интегрированные инструменты

    Для большей безопасности API и более четких границ для разработчиков эксперты API World призвали к инструментам безопасности, ориентированным на разработчиков…

  • Документация по API может улучшить или испортить опыт разработчиков

    На конференции API World на этой неделе эксперты освещают проблемы, связанные с плохой документацией API, и предлагают способы их устранения, например отказ от . ..

  • Разработчики хотят повышения производительности и эффективности в Java 20

    Java 20, вероятно, будет включать полезные функции, такие как улучшения параллелизма и профилирования, но добавочные обновления …

SearchCloudComputing

  • С помощью этого руководства настройте базовый рабочий процесс AWS Batch

    AWS Batch позволяет разработчикам запускать тысячи пакетов в AWS. Следуйте этому руководству, чтобы настроить этот сервис, создать свой собственный…

  • Партнеры Oracle теперь могут продавать Oracle Cloud как свои собственные

    Alloy, новая инфраструктурная платформа, позволяет партнерам и аффилированным с Oracle предприятиям перепродавать OCI клиентам в регулируемых …

  • Dell добавляет Project Frontier для периферии, расширяет гиперконвергентную инфраструктуру с помощью Azure

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

ПоискБезопасность

  • Гигиена безопасности и управление позой требуют новых инструментов

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

  • Оборудование для включения в набор компьютерных криминалистических инструментов

    Компьютерным экспертам-криминалистам для выполнения своей работы требуется нечто большее, чем программное обеспечение. Узнайте, какое оборудование представляет собой комплектный компьютер…

  • Советы начинающим компьютерным криминалистам

    Для тех, кто хочет стать следователем компьютерной криминалистики, узнайте о карьере и о том, чего ожидать, а также почему …

ПоискAWS

  • AWS Control Tower стремится упростить управление несколькими учетными записями

    Многие организации изо всех сил пытаются управлять своей огромной коллекцией учетных записей AWS, но Control Tower может помочь. Сервис автоматизирует…

  • Разбираем модель ценообразования Amazon EKS

    В модели ценообразования Amazon EKS есть несколько важных переменных. Покопайтесь в цифрах, чтобы убедиться, что вы развернули службу…

  • Сравните EKS и самоуправляемый Kubernetes на AWS

    Пользователи AWS сталкиваются с выбором при развертывании Kubernetes: запускать его самостоятельно на EC2 или позволить Amazon выполнять тяжелую работу с помощью EKS. См…

Что такое абстрактный класс?

Последнее обновление: 6 июня 2022 г.

Что означает абстрактный класс?

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


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

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

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

Advertisement

Techopedia объясняет абстрактный класс

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

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

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

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

Реклама

Поделись этим термином

Родственные термины
  • Класс
  • Интерфейс
  • Экземпляр
  • Объект
  • Объектно-ориентированное программирование
  • Объектно-ориентированный язык программирования
  • Базовый класс — .