Что значит имплементировать в программировании
В этой статье сделана попытка объяснить некоторые термины объектно-ориентированного программирования Java, и ответить на вопросы: что значит слово extends в определении класса? Что значит слово implements в определении класса? В чем разница между extends и implements? Что такое interface? Что такое @Override?
extends это ключевое слово, предназначенное для расширения реализации какого-то существующего класса. Создается новый класс на основе существующего, и этот новый класс расширяет (extends) возможности старого.
implements это ключевое слово, предназначенное для реализации интерфейса (interface).
Оба ключевых слова extends и implements используются, когда Вы создаете свой собственный класс на языке Java. Различие между ними в том, что implements означает, что Вы используете элементы интерфейса в Вашем классе, а extends означает, что Вы создаете подкласс от класса, который расширяете (extend). В новом классе Вы можете расширить только один класс, но Вы можете реализовать столько интерфейсов, сколько захотите.
Java не поддерживает множественное наследование (multiple inheritance) для классов. Эта проблема также решается путем использования нескольких интерфейсов.
@Override ключевое слово, которое позволяет в дочернем классе заново создать реализацию метода родительского класса.
Пример реализации интерфейса (как используется ключевое слово implements):
Интерфейс также может содержать в себе декларации полей констант, аннотации, интерфейсы и даже классы.
Теперь пример расширения класса (применение ключевого слова extends):
Вот что получится в результате:
Чтобы лучше понять работу терминов extends, implements, interface, @Override, необходимо изучить принципы объектно-ориентированного программирования: динамическое связывание (dynamic binding), полиморфизм (polymorphism) и общее наследование (general inheritance) [1].
Java — разница между extends и implements на примерах
После продолжительного программирования на C++ переходить на Java бывает болезненно. С одной стороны прославленный сборщик мусора, а с другой огромное множество принципиальных различий в подходах к программированию. Об одном таком отличии я сегодня расскажу подробнее.
Речь пойдет о наследовании в Java. В отличии от C++, где наследование могло быть множественным, здесь это не совсем так. Кроме того, привычный синтаксис через «:» заменился на целых два ключевых слова: extends и implements. Начну с первого.
Ключевое слово extends в Java
Действие ключевого слова в точности совпадает с его переводом, один класс расширяет другой, что является классическим наследованием. Правила видимости полей и методов сохранились: private доступны только в самом классе, protected в самом классе и во всех наследниках, к public методам и полям можно обращаться откуда угодно. Главное отличие от «сишного» наследования в том, что можно расширять только один класс. Я сейчас не буду рассуждать о том, насколько это удобно, скажу только, что со множественным наследованием в C++ постоянно творилась какая-то каша.
Небольшой пример наследования с помощью ключевого слова extends. Напишем класс Door, который будет описывать характеристики двери, мы можем создать объект этого класса и работать с ним, как с «просто дверью». С другой стороны напишем еще два класса: IronDoor и WoodDoor, которые будут расширять класс Door(== наследуются от класса Door), т.е. добавят свои характеристики к базовым.
Ключевое слово implements в Java
С ключевым словом implements связано чуть больше хитростей. Слово «имплементировать» можно понимать, как «реализовывать», а в тот самый момент, когда возникает слово «реализовывать», где-то недалеко появляются интерфейсы. Так вот конструкция public class Door implements Openable означает, что класс дверь реализует интерфейс «открывающийся». Следовательно класс должен переопределить все методы интерфейса. Главная фишка в том, что можно реализовывать сколь угодно много интерфейсов.
Зачем это нужно? Самый простой пример, который приходит в голову, два интерфейса: Openable и Closeble. В первом метод open, и метод close во втором. Они помогут научить нашу дверь закрываться и открываться.
В классах-потомках двери(железная и деревянная двери) тоже появятся методы открыть/закрыть, реализованные в классе Door. Но никто нам не запрещает их переопределить.
Заключение
Итак, главное отличие в том, что extends используется для наследования от класса в прямом смысле этого слова, а implements позволяет «реализовать интерфейс». На первый взгляд это кажется лишним, неудобным и непонятным, но стоит пару раз использовать по назначению и все встает на свои места. На сегодня у меня все, спасибо за внимание!
В чем разница между связями «Обобщение», «Реализация» и «Имплементация» на диаграмме классов UML?
Спецификацию UML касательно этого вопроса я понимаю следующим образом:
— связь generalization возникает между классами, когда один класс (наследник) основывается на другом классе (родителе). Судя по всему, здесь родительский класс обязательно должен быть конкретным классом (т.е. можно создавать его экземпляры).
— связь realization возникает между элементами диаграммы классов, когда один класс реализует поведение, определяемое другим классом. Скорее всего здесь речь идет о реализации поведения, определяемого интерфейсом или абстрактным классом.
— связь implementation — это подтип связи realization. Судя по всему, на одном конце связи — конкретный класс, а на другом — интерфейс (interface в Java, чисто виртуальный класс в C++).
Вопрос первый: насколько верна моя трактовка спецификации?
Вопрос второй: можно ли считать realization подтипом связи generalization?
Вопрос третий: если язык поддерживает множественное наследование (C++ например) и класс наследуется от двух конкретных классов — какая в таком случае связь между наследником и суперклассами?
Семантическую разницу между интерфейсом и абстрактным классом я понимаю. Родительский абстрактный класс определяет сущность объекта, а реализация классом некоторого интерфейса — лишь один из аспектов поведения класса (либо действий, которые можно выполнять над этим классом).
Вопрос четвертый: может ли быть такое, что в одном случае наследование от абстрактного класса порождает связь generalization, а в другом случае — realization.
Трактовка не совсем верна, я сейчас изложу свое мнение, а уж сравнить наши взгляды задача не из простых)) Основная проблема различие понятий в UML и ООП.
В целом по определениям: Со стороны клиента у каждого конкретного класса присутствуют: интерфейс (который состоит из методов, свойств и прочих языковых штук) и абстракция (это некое поведение, которое подразумевается при взаимодействии с его интерфейсом).
Generalization. Когда у классов совпадает поведение, получается можно свести их интерфейсы к единому — обобщить. Диаграмма обобщения показывает сходство некоторого аспекта поведения и абсолютное сходство интерфейса.
Realization. Когда часть поведения объекта выносится в отдельный класс — это называется реализацией. В программировании такой прием обычно называют делегированием, но UML похоже считает иначе.
Implementation. В терминологии UML это как раз означает декомпозицию некого объекта на составные части. В программировании этот термин означает совсем другое…
Абсолютное сходство интерфейса в Generalization звучит убедительно, а главное очень хочется в это верить. Но напрягает момент, что зачастую в классах-наследниках появляются публичные методы, которых не было у родителя, а в коде можно встретить понижающее приведение типа (downcasting).
Implementation как декомпозиция объекта на составляющие мне тоже нравится. Только не понял, почему у тебя implementation в UML конфликтует с implementation в программировании. Если судить по синтаксису, например, Java или PHP, то для того, чтобы показать, что класс реализует интерфейс, используется именно ключевое слово implement. Один класс в свою очередь может реализовывать множество интерфейсов (например, IComparable, IMovable и IDrawable). Получается, что такой класс — это объединение решения нескольких задач внутри одного класса, интерфейс которого состоит из совокупности всех интерфейсов, им реализуемых ResultingClassInterface =
В мануале IBM по UML про связь implementation написано следующее: The implementation relationship specifies that the realizing classifier must conform to the contract that the provided interface specifies. Это выполняется by design во всех языках программирования, поддерживающих интерфейсы в таком виде, как они понимаются например в Java, PHP или C#.
В том же самом мануале про связь realization написано вот что: You can model the following situations using realization relationships:
A component is realized by a set of classifiers that provide its implementation. Вот это уже действительно похоже на то, что класс предоставляет своим клиентам абстракцию, складывающуюся из сервисов классов, с которыми он находится в отношении realization плюс возможно его собственные публичные методы. При этом не гарантируется, что новый класс будет на 100 % повторять интерфейсы классов, чью реализацию он представляет. Следовательно, никто не запрещает нам realization провернуть за счет делегирования и обойтись вовсе без наследования в этом случае. При этом внешний вид связи (пунктирная линия с пустым треугольником на конце) ничем не отличается от вида связи implementation и напоминает связь generalization, что меня вводит в заблуждение. Делегирование же в свою очередь обычно на диаграммах представляется связью association (собирательно название для agregation или composition). Рискну предположить, что связь realization должна использоваться вместо association при делегировании, когда ВСЕ методы класса, входящего в связь с одной стороны (service provider), имеют свое отражение в публичных методах класса на другой стороне связи (т.е. отношение между методами биективное).
Ну и пока не ясен для меня вопрос, как следует поступать, когда в приложении существует множество разношерстных по своему назначению классов + один интерфейс, который большинство из них (но не все!) должны реализовывать. Причем реализация эта в 99% случаев должна быть по умолчанию одинакова. Писать в каждом из классов реализацию — ад. Отнаследовать все эти класса системы от базового класс MyObject implements IInterface, в котором будет представлена реализация интерфейса по умолчания (а-ля C# или Java) — вроде перебор. И как при этом должна выглядеть диаграмма классов UML?
Сие есть очень занимательно… никогда так глубоко не рыл, и вот…
Даже по-русски «realization» и «implementation» переводятся как реализация — это я вроде знал, а в литературе такого разделения не встречал нигде. Поиск «realization» в вики ничего тоже не дел, что уже настораживает. А вот про implementation написано, что это есть realization 
«Implementation is the realization of an application, or execution of a plan, idea, model, design, specification, standard, algorithm, or policy.»
Ладно, посчитаю, что это одно и то же.
Тогда имеем, что generalization — это просто наследование, не важно, от абстрактного класса или нет.
Implementation — реализация интерфейса (или чисто абстрактного класса).
Итого, про первый вопрос я не знаю, что сказать, но высказал свое мнение.
По второму — можно с некоторым уточнением, что это будет реализован (realized, implemnted) уже реальный метод, который в интерфейсе просто не мог быть реализован просто потому, что это интерфейс.
По третьему — тут будет просто несколько связей, в зависимости от типа — например если реализуется несколько интерфейсов — то будет несколько связей «implementation», то же касается и generalization.
По четвертому — если власс расширяет абстрактный и сам ничего не реализует (т.е. тоже является абстрактным), то тут просто не может быть реализации (implementation, realization) — т.е. тут чисто generalization. А если что-то реально реализуется — то тогда можно говорить о implementation (realization).
Что такое имплементация: значение, виды и сферы применения
Здравствуйте, уважаемые читатели блога KtoNaNovenkogo.ru. В XXI веке учёные стали чаще затрагивать в своих работах темы, связанные с глобализацией (это как?).
Сегодня наблюдается сближение не только экономик, но и культуры, традиций, идеологий разных государств. Изменения воплощаются в национальных правовых системах посредством имплементации.
Что означает этот сложный термин? Как международное право соотносится с внутригосударственным? И как сами государства относятся к процессу сближения? Ответы на эти вопросы вы найдёте в статье.
Английское слово implementation официально переводится ООН (что это за организация?) как «осуществление». Впервые термин употребил Комитет по правам человека в 1981 году.
Первоначальное значение слова «имплементировать» – претворять что-либо в жизнь.
Например, идею, концепцию, документ.
Сейчас термин в основном применяется в двух сферах:
С точки зрения права, имплементация – это реализация на внутригосударственном уровне обязательств, закреплённых в международных соглашениях.
Например, главы двух государств подписывают конвенцию (что это такое?) о правовой помощи по уголовным делам.
А в дальнейшем стороны предпринимают следующие шаги:
Учёные-правоведы рассматривают термин в узком и широком значении.
Например, для реализации взятых на себя обязательств государства создают специальные органы, выделяют часть денег из бюджета, сотрудничают с иностранными структурами.
А имплементация в программировании – что это? Если говорить простыми словами, выражение технологии, алгоритма или функции в исходном коде.
По сути, имплементировать – это реализовывать в ПО какой-либо функционал.
Виды имплементации в международном праве
В большинстве интернет-источников вы найдёте упоминание об инкорпорации, трансформации и отсылке. Однако правоведы выделяют и другие виды имплементации.
В общепринятой классификации критерием служит способ реализации государством международных обязательств.
| Имплементация | Что это простыми словами |
|---|---|
| Инкорпорация | Дословное воспроизведение текста международно-правовой нормы в национальном нормативном правовом акте. |
| Трансформация | Переработка международно-правовой нормы с учётом местных традиций и последующее её включение в национальное законодательство, изменение действующих и издание новых официальных документов. Трансформация обычно применяется в тех случаях, когда требуется сближение регулирования в странах, принадлежащих к разным правовым семьям (например, англо-саксонской и романо-германской). |
| Отсылка | Прямое указание в тексте национального нормативного правового акта на то, что для регулирования конкретного вопроса применяется международное соглашение. |
| Рецепция | Заимствование нормотворческими органами успешного правового опыта зарубежных стран со схожими социально-экономическими условиями. |
| Унификация | Сотрудничество государств в целях создания единообразного подхода к правовому регулированию ряда вопросов. Чаще всего унификация применяется в следующих сферах: международной торговли, уголовного права, экологической безопасности. |
Некоторые учёные (в частности, В.А.Вдовин) делят имплементацию на общую и специальную.
Общая предполагает лишь констатацию факта применения наднациональных актов для регулирования отношений внутри государства.
Так, в ч. 4 ст. 15 Конституции записано, что составной частью правовой системы выступают общепризнанные принципы и нормы международного права, а также международные договоры РФ.
Специальная имплементация – это изменение текущего национального законодательства. В том числе издание новых нормативных правовых актов и отмена тех, которые противоречат международно-правовым обязательствам государства.
Какое право важнее: международное или национальное
Ответ на этот вопрос зависит от правовых традиций конкретной страны. Большинство правоведов считают, что в будущем процессы глобализации только усилятся.
На первый план выйдут проблемы, решение которых требует совместных усилий:
Это приведёт к превалированию международных норм права над национальными. Уже сейчас многие страны закрепили в основных законах положение о таком приоритете (это как?).
Согласно Конституции РФ, в случае противоречия закона и международного договора должны применяться положения последнего. Поэтому многие юристы пришли к выводу о примате международного права над национальным.
Однако в июле 2015 года Конституционный Суд РФ изложил в своём постановлении противоположную точку зрения. Он написал, что государство в порядке исключения вправе отступить от исполнения возлагаемых на него обязательств, если такое отступление является единственно возможным вариантом избежать нарушения основополагающих принципов и норм Конституции.
Заключение
Итак, имплементация – это практическая реализация внутри государства международно-правовых норм в целях исполнения взятых на себя обязательств.
Большая часть работы возлагается на нормотворческие органы. В российском законодательстве чаще можно встретить отсылки к соглашениям или переработанные нормы, чем дословные формулировки. Вопрос о соотношении международного и национального права в РФ остаётся открытым.
Автор статьи: Белоусова Наталья
Удачи вам! До скорых встреч на страницах блога KtoNaNovenkogo.ru
Эта статья относится к рубрикам:
Комментарии и отзывы (1)
О боги, каких только замысловатых слов не придумают. Неужели нельзя как-то попроще всё называть. А это слово ещё попробуй выговори.
Название имплементации и название результата
Я хотел написать этот пост ещё в июле, но никак не мог, о ирония, решить, как его назвать. Удачные термины пришли мне в голову только после доклада Кейт Грегори на CppCon, и теперь я наконец могу рассказать вам, как не надо называть функции.
Пример 1: std::log2p1()
То есть для любого натурального числа функция возвращает его двоичный логарифм плюс 1, а для 0 возвращает 0. И это не школьная задачка на оператор if/else, это действительно полезная вещь — минимальное число бит, в которое поместится данное значение. Вот только догадаться об этом по названию функции практически невозможно.
Пример 2: std::bless()
Сейчас будет не про названия
Небольшое отступление: в С++ арифметика указателей работает только с указателями на элементы массива. Что, в принципе, логично: в общем случае набор соседних объектов неизвестен и “в десяти байтах справа от переменной i ” может оказаться что угодно. Это однозначно неопределённое поведение.
Но такое ограничение объявляет неопределённым поведением огромное количество существующего кода. Например, вот такую упрощённую имплементацию std::vector ::reserve() :
Мы выделили память, перенесли все объекты и теперь пытаемся убедиться, что указатели указывают куда надо. Вот только последние три строчки неопределены, потому что содержат арифметические операции над указателями вне массива!
Разумеется, виноват тут не программист. Проблема в самом стандарте C++, который объявляет неопределённым поведением этот очевидно разумный кусок кода. Поэтому P0593 предлагает исправить стандарт, добавив некоторым функциям (вроде ::operator new и std::malloc ) способность создавать массивы по мере необходимости. Все созданные ими указатели будут магическим образом становиться указателями на массивы, и с ними можно будет совершать арифметические операции.
Всё ещё не про названия, потерпите секундочку.
Название std::bless было временным.
Мне эти варианты не понравились.
Пример 3: std::partial_sort_copy()
Кейт утверждает, что std::partial_sort_copy — так себе название, и я с ней согласен.
Название имплементации и название результата
Ни одно из перечисленных названий не является, строго говоря, неверным: они все прекрасно описывают то, что делает функция. std::log2p1() действительно считает двоичный логарифм и прибавляет к нему единицу; implicitly_create_objects() имплицитно создаёт объекты, а std::partial_sort_copy() частично сортирует контейнер и копирует результат. Тем не менее, все эти названия мне не нравятся, потому что они бесполезны.
Точно так же никому не надо “имплицитно создавать объекты” или “проводить частичную сортировку копии вектора” — им нужно переиспользовать память или получить 5 наибольших значений в порядке убывания. Что-то типа recycle_storage() (что тоже предлагали в качестве названия std::bless ) и top_n_sorted() было бы гораздо понятнее.
Называть функцию на основании её спецификации — значит создавать на ровном месте непонимание между разработчиком библиотеки и её пользователем. Всегда нужно помнить, когда и как функция будет использоваться.
Пример 4: std::popcount()
С другой стороны, std::popcount() идеально подходит для этой функции, потому что она вызывает ассемблерную инструкцию popcount. Это не то что название имплементации — это полное её описание.
Тем не менее, в данном случае разрыв между разработчиками языка и программистами не так уж и велик. Инструкция, считающая количество единиц в двоичном слове, называется popcount с шестидесятых. Для человека, хоть сколько-нибудь разбирающегося в операциях с битами, такое название абсолютно очевидно.
Кстати, хороший вопрос: придумывать ли названия, удобные для новичков, или оставить привычные для олдфагов?
Хэппи-энд?
Разумеется, std::partial_sort_copy() уже не переименуют — под этим названием она вошла в стандарт ещё в 1998. Но хотя бы std::log2p1 исправили, и то неплохо.
Придумывая названия функций, нужно думать о том, кто ими будет пользоваться и чего он от них захочет. Как выразилась Кейт, именование требует эмпатии.





