Интерфейс как тип в Java? - PullRequest
       6

Интерфейс как тип в Java?

32 голосов
/ 02 сентября 2011

С Учебные руководства по Java :

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

Может ли кто-нибудь предоставить мне базовый псевдотип для этого. Я не понял жирных линий.

Ответы [ 11 ]

55 голосов
/ 02 сентября 2011

Давайте объявим два интерфейса и класс, который реализует их оба:

interface I1 { }

interface I2 { }

class C implements I1, I2 { }

объекты могут иметь несколько типов

В следующем коде видно, что экземпляр C имеет тип C, а также I1 и I2:

C c = new C();

boolean isC = (c instanceof C);   //true
boolean isI1 = (c instanceof I1); //true
boolean isI2 = (c instanceof I2); //true

Теперь давайте объявим класс B, который также реализует I1:

class B implements I1 { }

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

Если мы объявим переменную типа I1, мы можем установить для нее экземпляр C, а затем переназначить его для экземпляра B:

I1 i1 = new C();
i1 = new B();

Мы также можем переназначить его на экземпляр D, где D extends C:

i1 = new D();

...

class D extends C { }
11 голосов
/ 02 сентября 2011

Рассмотрим следующий пример:

Serializable s = new ArrayList();

В Java это допустимый код, даже если Serializable является интерфейсом, поскольку ArrayList реализует Serializable.Таким образом, в этом случае мы рассматриваем s как переменную типа Serializable.

Теперь предположим, что мы приведем приведенный выше код следующим образом:

s = "String object";

Этотакже допустимо, потому что String также реализует Serializable.Поскольку мы объявили s как тип Serializable, он может указывать на любой объект , который реализует этот интерфейс.

5 голосов
/ 02 сентября 2011

объекты могут иметь несколько типов

Рассмотрим следующий фрагмент:

public class MyClass extends ParentClass implements Interface1, Interface2 {    
    //some code    
}

Этот класс можно использовать в разных местах следующим образом:

MyClass m1 = new MyClass();
ParentClass p = new MyClass();
Interface1 i1 = new MyClass();
Interface2 i2 = new MyClass();

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

Рассмотрим последние две строки вВ предыдущем фрагменте переменная типа Interface1 может ссылаться на любой объект, реализующий этот интерфейс, поэтому, если у нас есть другой класс, реализующий Interface1, скажем, MyClass2, то

Interface1 i1 = new MyClass();
Interface1 i2 = new MyClasss2();
i1 = i2;
i1 = new MyClass2();

Все предыдущие назначения действительны, поскольку MyClass и MyClass2реализует интерфейс 1

4 голосов
/ 02 сентября 2011
class Ball extends Rubber implements Jumping, Rolling, Squeezing {
   public void jump(){}
   public void roll(){}
   public void squeeze(){}
}

Ball b = new Ball();
Jumping j = new Ball();
j.jump();

//j.roll();         //CTE: Cannot resolve method roll()
((Ball) j).roll();  //but it still can be called if explicit cast to type Ball is used
2 голосов
/ 11 февраля 2015

Очень простой пример -

List<String> list1=new ArrayList<String>();

Поскольку ArrayList реализует List, поэтому мы можем использовать переменную интерфейса List, т.е. list1, для ссылки на объект, созданный Arraylist.

2 голосов
/ 02 сентября 2011

объекты могут иметь несколько типов

Пример:

public class Foo implements Runnable, Callable<Integer> {
  public void run() {}
  public Integer call() {return 1;}
}

Foo foo = new Foo();
Runnable r = foo;
Callable<Integer> c = foo;

Пример:

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

Runnable r = new Foo();
r = Thread.currentThread();   //Thread implements Runnable
2 голосов
/ 02 сентября 2011

String реализует несколько интерфейсов, поэтому он имеет несколько типов:

String s = "A String";
Comparable<String> comp = s;
CharSequece cs = s;
Serializable ser = s;

Интерфейс CharSequence реализован несколькими классами, поэтому ссылка CharSequence может содержать все виды объектов:

CharSequence cs = "A String";
cs = new StringBuilder();
cs = new Segment();
2 голосов
/ 02 сентября 2011

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

Например, "bimmelim" имеет тип String, но также имеет тип Object. Интерфейсы не изменяют это, за исключением того, что "bimmelim" также имеет тип Serializable, CharSequence и другие.

На самом деле, это, возможно, спорно, стоит ли говорить, что "bimmelim" 1014 * «имеет» тип Object, но, конечно, ссылка на него будет вписываться в Object переменных.

Если переменная объявлена ​​как тип интерфейса ... например

CharSequence x ;

... тогда его значение может ссылаться на объект String, такой как "bimmelim", или это может быть StringBuffer, который является другим типом, реализующим CharSequence.

1 голос
/ 02 сентября 2011

Возьмем в качестве примера интерфейс Collection из стандартных библиотек Java. Любая переменная, объявленная как тип Collection, может затем быть назначена объекту класса, который реализует интерфейс Collection, например, ArrayList, Stack, ... см. Связанные документы для большего количества примеров.

1 голос
/ 02 сентября 2011

Рассмотрим следующие определения классов и интерфейсов:

public class A { }

public class B extends A implements I { }

public interface I { }

Следующие утверждения являются законными:

A first = new A();
B second = new B();
A third = new B();
I fourth = new B();

Поскольку B реализует I и расширяет A, его можно использовать в качестве значения везде, где ожидается «I» или «A».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...