2012-08-31 2 views
5

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

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

+3

, потому что в противном случае вы бы получили беспорядок регулярной (C++, как) множественным наследование, которое обычно является избыточным комплексообразованием. – amit

+0

Мне было предложено это на собеседовании, не могли бы вы рассказать об этом –

+2

Интерфейсы - это * не * "множественное наследование". Множественное наследование уродливое, интерфейсы прекрасны;) И интерфейсы не * переопределены *, они «реализованы». Чтобы понять Java-интерфейсы, вам нужно понять «полиморфизм OO». Интерфейсы Java - это КОНТРАКТ, который должен выполняться классом реализации HONOR. Интерфейсы Java - это «спецификация»; класс реализации обеспечивает фактическое «поведение». – paulsm4

ответ

13

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

Дизайнеры Java (и C#, если на то пошло) решили не включать его, поскольку он представил программистов на C++ часто с очень трудными для отладки проблем. Вы можете решить практически все проблемы, требующие истинного множественного наследования с внедрением нескольких интерфейсов, поэтому компромисс был сочтено им полезным.

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

+0

может быть более конкретным о типах и поведении, пример ? пожалуйста, –

+1

Если у вас есть класс, он всегда будет иметь * состояние *, т.е. поля. Например. для гипотетического класса Person, который может быть именем. Тогда классы имеют * поведение * в виде методов. Методы делают определенные вещи и определенным образом. Интерфейсы в контрастном состоянии определяют только имя и аргументы методов в виде контракта. Как класс реализации реализует эти методы, зависит от класса, поэтому интерфейс не может обеспечить поведение, поскольку он не имеет реализации метода. – Joey

+0

тем, что вы имеете в виду, каждый производный класс в java, который реализует интерфейс, будет иметь гибкость в том, чтобы иметь собственную защиту метода в интерфейсе? –

1

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

2

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

2

Интерфейсы имеют постоянные переменные (public + static + final) и абстрактные методы (public & abstract). Они предназначены для использования классами, реализующими интерфейсы.

Интерфейсы просто говорят: «Есть контракт», который, если вы хотите использовать, должен придерживаться некоторых правил (дать реализацию всем абстрактным методам).

Множественное наследование отсутствует в Java, убедившись, что класс может распространять только 1 класс, чтобы избежать diamond problem. В любом случае вы можете иметь множественное наследование типов в Java с помощью интерфейсов.

0

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

public interface Flyable 
{ 
public void fly(); 
} 

, потому что сам интерфейс не собирается ничего делать

интерфейс определяет контракт.

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

Таким образом, интерфейс Flyable ничего не делает, кроме как определяет, что имплантированные объекты FlyableObjects будут летать.

как:

class Rocket implements Flyable 
{ 
public void fly() 
{ 
// do the stuffs. 
} 
} 

interface

и конечно же мы можем достичь множественного наследования также только и только через интерфейс.

1

Простой ответ:

Интерфейс обеспечивает стандарт для реализации.

Объяснение:
В Java интерфейс похож на абстрактный класс в том, что его члены не реализованы. Например,

public interface Comparable  
{ boolean less(Object m); 
    boolean greater(Object m); 
    boolean lessEqual(Object m); 
    boolean greaterEqual(Object m); 
} 

Интерфейс обеспечивает стандарт для реализации.
Преимущество использования интерфейсов в том, что они имитируют множественное наследование. Все классы в Java должны иметь ровно один базовый класс, единственным исключением является java.lang.Object (корневой класс системы типа Java); множественное наследование классов не допускается в java.

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

Интерфейс создает протокол , что классы могут реализовывать. Обратите внимание, что можно расширить интерфейс (чтобы получить новый интерфейс), так как вы можете расширить класс . Можно фактически расширить несколько интерфейсов. Интерфейсы таким образом пользуются преимуществами множественного наследования. (Занятия нет.) Есть Почти нет недостатков для множественного наследования интерфейса (Конфликт мелких имен - это одно исключение). Есть большие недостатки для множественного наследования реализации, как в C++. К ним относятся: эффективность соображения, а также семантическая трудность определения того, какой код будет выполнен в некоторых случаях.

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

public class Polynomial implements Comparable 
{ . . . 
    boolean less(Object m){ . . . } 
    boolean greater(Object m){ . . . } 
    boolean lessEqual(Object m){ . . . } 
    boolean greaterEqual(Object m){ . . . } 

    Polynomial multiply(Polynomial P){ . . . } 
    . . . 
} 

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

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

Ссылки:
Interface
Interfaces
Interface Wiki

+2

-1; Если вы берете текст с сайта, то вы должны хотя бы дать ссылку на оригинал. Текст разорван с этого сайта: http://csis.pace.edu/~bergin/papers/Interface.html – maba

+0

@maba, Извините за неудобства, я просто хочу объяснить тему, я взял из многих мест и отредактировал ее много раз. если вам действительно нужны ссылки, тогда этот ответ будет заполнен ссылками! ** Вам нужны ссылки или хороший ответ? лучше вы можете сосредоточиться, чтобы улучшить ответ, если вы в состоянии это сделать. –

+0

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

0

если интерфейсы были тела, то она вернула бы Смертельный DAIMOND проблемы смерти.

Рассмотрим пример, имеющий интерфейсы с органами

interface A { 
    void print(){ System.out.print("A") } 
} 

interface B { 
    void print(){ System.out.print("B") } 
} 

interface C extends A, B { 
    // now since A and B have bodies interfaces would have had choice to not to override the default behavior 
} 

public class C_Implementer implements C{ 
    public static void main(String args[]){ 
     C c = new C_Implementer(); 
     c.print(); // gotcha!!!!! what should it print, A or B???? 
    } 
} 
0

Вы спрашиваете: «Почему Java не поддерживает множественное наследование реализации?»

Это обсуждается в учебниках Java, Multiple Inheritance of State, Implementation, and Type, но я хотел привести конкретный пример проблем множественного наследования реализации (а также в конце концов нового решения по языковым функциям).

Представьте себе два интерфейса (в нашей предлагаемой версии Java, которая позволяет телам методов интерфейса), которые определяют метод с тем же именем.

public interface FaceOne { 
    public void method() { 
     System.out.println("FaceOne Version"); 
    } 
} 

public interface FaceTwo { 
    public void method() { 
     System.out.println("FaceTwo Version"); 
    } 
} 

И класс реализует оба интерфейса, но не переопределяет метод.

public class Inheriter implements FaceOne, FaceTwo { 

} 

Когда я звоню Inheriter.method(), который работает так как класс наследует метод от своих предков, возникает проблема: делает вывод на печать «FaceOne Version» или «FaceTwo версия»?

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

Именно поэтому Java не поддерживает множественное наследование реализации.


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

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

Затем используйте аналогичную запись, как that of accessing an enclosing instance for an inner class, для доступа к определенному интерфейсу предка с super. Класс Inheriter затем есть несколько вариантов:

  • Не называйте super.method(), а только использовать вновь определенную реализацию.

  • Используйте FaceOne.super.method(), чтобы сделать унаследованный результат реализации по умолчанию «FaceOne Version».

  • Используйте FaceTwo.super.method(), чтобы сделать унаследованный результат реализации по умолчанию «FaceTwo Version».

  • Используйте комбинацию выше:

Одна реализация может быть:

@Override 
public void method() { 
    FaceOne.super.method(); 
    FaceTwo.super.method(); 
    System.out.println("Inheriter Version"); 
} 

Выведение:

FaceOne Версия

FaceTwo Версия

Inheriter Версия


Edit: По this question это, по-видимому, как именно по умолчанию реализации структурированы в Java 8.

Смежные вопросы