Что такое имплементация в java
Перейти к содержимому

Что такое имплементация в java

  • автор:

Implementing an Interface

To declare a class that implements an interface, you include an implements clause in the class declaration. Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class. By convention, the implements clause follows the extends clause, if there is one.

A Sample Interface, Relatable

Consider an interface that defines how to compare the size of objects.

If you want to be able to compare the size of similar objects, no matter what they are, the class that instantiates them should implement Relatable .

Any class can implement Relatable if there is some way to compare the relative "size" of objects instantiated from the class. For strings, it could be number of characters; for books, it could be number of pages; for students, it could be weight; and so forth. For planar geometric objects, area would be a good choice (see the RectanglePlus class that follows), while volume would work for three-dimensional geometric objects. All such classes can implement the isLargerThan() method.

If you know that a class implements Relatable , then you know that you can compare the size of the objects instantiated from that class.

Implementing the Relatable Interface

Here is the Rectangle class that was presented in the Creating Objects section, rewritten to implement Relatable .

Because RectanglePlus implements Relatable , the size of any two RectanglePlus objects can be compared.

Интерфейсы Java – что это такое?

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

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

Пример интерфейса Java

Вот простой пример интерфейса Java:

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

Приведенный выше пример содержит одну переменную и один метод. Доступ к переменной можно получить непосредственно из интерфейса, например так:

Как видите, доступ к переменной очень похож на доступ к статической переменной в классе.

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

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

Вот класс, который реализует интерфейс MyInterface, показанный выше:

Обратите внимание, реализует часть MyInterface вышеупомянутого объявления класса. Это сообщает компилятору Java, что класс MyInterfaceImpl реализует интерфейс MyInterface.

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

Экземпляры интерфейса

Как только класс Java реализует интерфейс Java, вы можете использовать экземпляр этого класса в качестве экземпляра. Вот пример:

Обратите внимание, как объявлена переменная типа интерфейса MyInterface, в то время как созданный объект имеет тип MyInterfaceImpl. Java позволяет это, потому что класс MyInterfaceImpl реализует MyInterface. Затем вы можете ссылаться на экземпляры класса MyInterfaceImpl как на экземпляры MyInterface.

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

Реализация нескольких интерфейсов

Класс Java может реализовывать несколько интерфейсов. В этом случае класс должен реализовать все методы, объявленные во всех реализованных интерфейсах. Вот пример:

Этот класс реализует два, называемых MyInterface и MyOtherInterface. Вы перечисляете имена для реализации после ключевого слова Implements, разделенных запятой.

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

реализованные классом выше:

Как видите, каждый интерфейс содержит один метод. Эти методы реализуются классом MyInterfaceImpl.

Перекрывающиеся подписи метода

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

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

Какие типы Java могут реализовывать интерфейсы?

Следующие типы могут реализовывать интерфейсы:

  • Класс;
  • абстрактный класс; ; ;
  • Динамический Прокси

Переменные интерфейса

Интерфейс может содержать как переменные, так и константы. Однако часто не имеет смысла помещать переменные. В некоторых случаях может иметь смысл определять константы.

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

Все переменные в интерфейсе являются открытыми, даже если вы опустите ключевое слово public в объявлении переменной.

Методы интерфейса

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

Все методы являются открытыми, даже если вы опустите ключевое слово public в объявлении метода.

Методы интерфейса по умолчанию

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

Если API просто добавляет метод, все классы, которые реализуют интерфейс, должны реализовать этот новый метод. Это хорошо, если все реализующие классы расположены в API. Но если некоторые реализующие классы находятся в клиентском коде API(код, который использует API), то этот код нарушается.

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

Теперь представьте, что проект использует этот API и реализовал ResourceLoader следующим образом:

Если разработчик API хочет добавить еще один метод в ResourceLoader, то класс FileLoader будет нарушен при обновлении этого проекта до новой версии API.

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

Вы помечаете метод как метод по умолчанию, используя ключевое слово. Вот пример:

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

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

Статические методы интерфейса

Статические методы в Java должны иметь реализацию.

Вызов статического метода выглядит и работает так же, как вызов статического метода в классе. Вот пример вызова статического метода print() из вышеуказанного MyInterface:

Статические методы в интерфейсах могут быть полезны, когда у вас есть несколько служебных методов, которые вы хотели бы сделать доступными. Например, Vehicle может иметь статический метод printVehicle(Vehicle v).

Интерфейсы и наследование

Интерфейс Java может наследоваться от другого, как классы могут наследовать от других классов. Вы указываете наследование, используя ключевое слово extends.

MySubInterface расширяет MySuperInterface. Это означает, что MySubInterface наследует все поля и методы от MySuperInterface. Это означает, что если класс реализует MySubInterface, этот класс должен реализовать все методы, определенные как в MySubInterface, так и в MySuperInterface.

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

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

Вот пример интерфейса Java, который наследуется от нескольких интерфейсов:

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

Наследование и методы по умолчанию

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

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

В обеих вышеупомянутых ситуациях компилятор Java требует, чтобы класс, реализующий интерфейс(ы), явно реализовал метод, который вызывает проблему. Таким образом, нет сомнений в том, какую реализацию будет иметь класс. Реализация в классе имеет приоритет над любыми реализациями по умолчанию.

Интерфейсы и полиморфизм

Java-интерфейсы – это способ достижения полиморфизма. Полиморфизм – это концепция, которая требует некоторой практики и мысли, чтобы овладеть ею. По сути, полиморфизм означает, что экземпляр класса(объекта) можно использовать так, как если бы он был разных типов. Здесь тип означает либо класс, либо интерфейс.

Посмотрите на эту простую диаграмму классов:

Two parallel class hierarchies used in the same application.

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

Теперь представьте, что вам нужно иметь возможность хранить эти объекты в базе данных, а также сериализовать их в XML, JSON или другие форматы. Вы хотите, чтобы это было реализовано с использованием одного метода для каждой операции, доступного для каждого объекта Car, Truck или Vehicle. Метод store(), метод serializeToXML() и метод serializeToJSON().

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

Где в приведенной выше схеме вы бы поместили эти три метода, чтобы они были доступны для всех классов?

Одним из способов решения этой проблемы было бы создание общего суперкласса для класса Vehicle и Driver, который имеет методы хранения и сериализации. Однако это приведет к концептуальному беспорядку. Иерархия классов больше не будет моделировать транспортные средства и водителей, но также будет привязана к механизмам хранения и сериализации, используемым в вашем приложении.

Лучшим решением было бы создать некоторые интерфейсы с включенными методами хранения и сериализации и позволить классам реализовать эти интерфейсы. Вот примеры таких интерфейсов:

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

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

Универсальные интерфейсы

Этот интерфейс представляет интерфейс, который содержит единственный метод, который называется производством(), который может произвести единственный объект. Так как возвращаемое значение yield() – Object, он может возвращать любой объект Java.

Как вы можете видеть, поскольку универсальный тип для экземпляра CarProducer установлен на Car, больше нет необходимости приводить объект, возвращенный из метода yield(), поскольку в объявлении исходного метода в интерфейсе MyProducer указано, что этот метод возвращает тот же тип, который указан в универсальном типе при использовании.

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

Обобщения Java более подробно описаны в моем руководстве по обобщению Java.

Функциональные интерфейсы

С Java 8 была введена новая концепция, называемая функциональными интерфейсами. Короче говоря, функциональный интерфейс – это интерфейс с единственным нереализованным методом(нестандартный, нестатический метод). Я объяснил функциональные интерфейсы в моем учебнике по функциональному интерфейсу Java, который является частью моего учебника по функциональному программированию на Java. ,

Интерфейсы в Java

Сегодня у вас прямо день знаний. Еще одна новая и интересная тема — это интерфейсы.

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

Вот несколько полезных фактов об интерфейсах:

1. Объявление интерфейса

  1. Вместо слова class пишем interface .
  2. Содержит только абстрактные методы (слово abstract писать не нужно)
  3. На самом деле у интерфейсов все методы – public

Интерфейс может наследоваться только от интерфейсов. Зато родителей у интерфейса может быть много. Еще говорят, что в Java есть множественное наследование интерфейсов. Примеры:

3. Наследование классов от интерфейсов

Класс может наследоваться от нескольких интерфейсов (и только от одного класса). При этом используется ключевое слово implements . Пример:

Класс ChessItem объявлен абстрактным: он реализовал все унаследованные методы, кроме draw . Т.е. класс ChessItem содержит один абстрактный метод — draw() .

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

4. Переменные

И самое важное: в интерфейсах нельзя объявлять переменные (хотя статические можно).

А зачем же нужны интерфейсы? Когда их используют? У интерфейсов есть два сильных преимущества по сравнению с классами, которые мы рассмотрим далее.

2. Отделение «описания методов» от их реализации.

Раньше мы уже рассказывали, что если вы хотите разрешить вызывать методы своего класса из других классов, то их нужно пометить ключевым словом public . Если же хотите, чтобы какие-то методы можно было вызывать только из этого же класса, их нужно помечать ключевым словом private. Другими словами, мы делим методы класса на две категории: «для всех» и «только для своих».

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

Было Стало

Мы разбили наш класс на два: интерфейс и класс , унаследованный от интерфейса . И в чем тут преимущество?

Один и тот же интерфейс могут реализовывать (наследовать) различные классы. И у каждого может быть свое поведение. Так же, как ArrayList и Li nkedList — это две различные реализации интерфейса List .

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

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

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

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

В Java пришли к компромиссу: запретили множественное наследование классов, но разрешили множественное наследование интерфейсов. Интерфейс может иметь несколько интерфейсов-родителей. Класс может иметь несколько интерфейсов-родителей и только один класс-родитель.

Почему же множественное наследование классов запретили, а интерфейсов — разрешили? Все дело в так называемом пирамидальном наследовании:

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

Когда класс B наследуется от класса A, он ничего не знает о классах C и D. Поэтому он использует переменные класса A так, как считает нужным. Класс C делает то же самое: использует переменные класса A, но уже другим способом. И в классе D это все выливается в конфликт.

Давайте рассмотрим такой простой пример. Допустим, у нас есть 3 класса:

Класс Data хранит у себя переменную value . Его класс-наследник XCoordinate использует ее для того, чтобы хранить в ней переменную x , а класс-наследник YCoordinate использует ее для того, чтобы хранить в ней переменную y .

И это работает. По отдельности. Но вот если мы захотим унаследовать класс XYCoordinates от обоих классов, XCoordinate и YCoordinate , получим неработающий код. У этого класса будут методы его классов-предков, но работать они будут неправильно, т.к. переменная value у них одна.

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

Implements vs extends: When to use? What's the difference?

Please explain in an easy to understand language or a link to some article.

19 Answers 19

extends is for extending a class.

implements is for implementing an interface

The difference between an interface and a regular class is that in an interface you can not implement any of the declared methods. Only the class that "implements" the interface can implement the methods. The C++ equivalent of an interface would be an abstract class (not EXACTLY the same but pretty much).

Also java doesn’t support multiple inheritance for classes. This is solved by using multiple interfaces.

now extending a class

Also, note that an @Override tag is not required for implementing an interface, as there is nothing in the original interface methods to be overridden

I suggest you do some more research on dynamic binding, polymorphism and in general inheritance in Object-oriented programming

I notice you have some C++ questions in your profile. If you understand the concept of multiple-inheritance from C++ (referring to classes that inherit characteristics from more than one other class), Java does not allow this, but it does have keyword interface , which is sort of like a pure virtual class in C++. As mentioned by lots of people, you extend a class (and you can only extend from one), and you implement an interface — but your class can implement as many interfaces as you like.

Ie, these keywords and the rules governing their use delineate the possibilities for multiple-inheritance in Java (you can only have one super class, but you can implement multiple interfaces).

Arashsoft's user avatar

CodeClown42's user avatar

Generally implements used for implementing an interface and extends used for extension of base class behaviour or abstract class.

extends: A derived class can extend a base class. You may redefine the behaviour of an established relation. Derived class «is a» base class type

implements: You are implementing a contract. The class implementing the interface «has a» capability.

With java 8 release, interface can have default methods in interface, which provides implementation in interface itself.

Refer to this question for when to use each of them:

Example to understand things.

Important points to understand:

  1. Dog and Cat are animals and they extended remember () and protectOwner () by sharing name,lifeExpentency from Animal
  2. Cat can climb() but Dog does not. Dog can think() but Cat does not. These specific capabilities are added to Cat and Dog by implementing that capability.
  3. Man is not an animal but he can Think,Learn,Apply,Climb

By going through these examples, you can understand that

Unrelated classes can have capabilities through interface but related classes override behaviour through extension of base classes.

Ravindra babu's user avatar

As shown in the figure given below, a class extends another class, an interface extends another interface but a class implements an interface. enter image description here

Priyantha's user avatar

extends is for when you’re inheriting from a base class (i.e. extending its functionality).

implements is for when you’re implementing an interface.

A class can only «implement» an interface . A class only «extends» a class . Likewise, an interface can extend another interface .

A class can only extend one other class . A class can implement several interface s.

If instead you are more interested in knowing when to use abstract class es and interface s, refer to this thread: Interface vs Abstract Class (general OO)

An interface is a description of the actions that an object can do. for example when you flip a light switch, the light goes on, you don’t care how, just that it does. In Object Oriented Programming, an Interface is a description of all functions that an object must have in order to be an «X». Again, as an example, anything that «ACTS LIKE» a light, should have a turn_on() method and a turn_off() method. The purpose of interfaces is to allow the computer to enforce these properties and to know that an object of TYPE T (whatever the interface is ) must have functions called X,Y,Z, etc.

An interface is a programming structure/syntax that allows the computer to enforce certain properties on an object (class). For example, say we have a car class and a scooter class and a truck class. Each of these three classes should have a start_engine() action. How the «engine is started» for each vehicle is left to each particular class, but the fact that they must have a start_engine action is the domain of the interface.

Priyantha's user avatar

Both keywords are used when creating your own new class in the Java language.

Difference: implements means you are using the elements of a Java Interface in your class. extends means that you are creating a subclass of the base class you are extending. You can only extend one class in your child class, but you can implement as many interfaces as you would like.

Refer to oracle documentation page on interface for more details.

This can help to clarify what an interface is, and the conventions around using them.

Ravindra babu's user avatar

Extends : This is used to get attributes of a parent class into child class and may contain already defined methods that can be overridden in the child class.

Implements : This is used to implement an interface (parent class with functions signatures only but not their definitions) by defining it in the child class.

There is one special condition: "What if I want a new Interface to be the child of an existing interface?". In the above condition, the child interface extends the parent interface.

A and B are both classes or both interfaces

A is a class and B is an interface

The remaining case where A is an interface and B is a class is not legal in Java.

Implements is used for Interfaces and extends is used to extend a class.

To make it more clearer in easier terms,an interface is like it sound — an interface — a model, that you need to apply,follow, along with your ideas to it.

Extend is used for classes,here,you are extending something that already exists by adding more functionality to it.

A few more notes:

an interface can extend another interface.

And when you need to choose between implementing an interface or extending a class for a particular scenario, go for implementing an interface. Because a class can implement multiple interfaces but extend only one class.

We use SubClass extends SuperClass only when the subclass wants to use some functionality (methods or instance variables) that is already declared in the SuperClass, or if I want to slightly modify the functionality of the SuperClass (Method overriding). But say, I have an Animal class(SuperClass) and a Dog class (SubClass) and there are few methods that I have defined in the Animal class eg. doEat(); , doSleep(); . and many more.

Now, my Dog class can simply extend the Animal class, if i want my dog to use any of the methods declared in the Animal class I can invoke those methods by simply creating a Dog object. So this way I can guarantee that I have a dog that can eat and sleep and do whatever else I want the dog to do.

Now, imagine, one day some Cat lover comes into our workspace and she tries to extend the Animal class(cats also eat and sleep). She makes a Cat object and starts invoking the methods.

But, say, someone tries to make an object of the Animal class. You can tell how a cat sleeps, you can tell how a dog eats, you can tell how an elephant drinks. But it does not make any sense in making an object of the Animal class. Because it is a template and we do not want any general way of eating.

So instead, I will prefer to make an abstract class that no one can instantiate but can be used as a template for other classes.

So to conclude, Interface is nothing but an abstract class(a pure abstract class) which contains no method implementations but only the definitions(the templates). So whoever implements the interface just knows that they have the templates of doEat(); and doSleep(); but they have to define their own doEat(); and doSleep(); methods according to their need.

You extend only when you want to reuse some part of the SuperClass(but keep in mind, you can always override the methods of your SuperClass according to your need) and you implement when you want the templates and you want to define them on your own(according to your need).

I will share with you a piece of code: You try it with different sets of inputs and look at the results.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *