Подтвердить что ты не робот

Лить объект в интерфейс в java?

Если мы передадим объект интерфейсу, этот объект не сможет вызвать его собственные методы? в следующем примере myObj сможет вызывать только методы MyInterface?

MyInterface myObj = new Obj();

Если это правильно, в чем разница между этими двумя объектами:

MyInterface myObj = new Obj();

MyInterface mySec = new Sec();

Спасибо за помощь

4b9b3361

Ответ 1

MyInterface myObj = new Obj(); 
MyInterface mySec = new Sec(); 

Чтобы это было законным, обе Obj и Sec должны быть исполнителями MyInterface. Разница между этими двумя объектами будет заключаться в том, как они обеспечивают эту реализацию. Obj и Sec могут делать две очень разные или очень похожие вещи, но их общность заключается в том, что они будут придерживаться контракта, на который вы могли бы положиться. У вас есть метод

public void doSomethingWith(MyInterface thing) {
     thing.frob();
}

Каждый объект, myObj и mySec, может быть передан в этот метод, и этот метод мог бы затем использовать этот метод frob (предполагая, что frob является частью объявления интерфейса). Это освобождение. Это позволяет делать очень мощные вещи, программируя интерфейсы, а не реализации. Например, вы можете расширить функциональность классов и не изменять строку кода в этих классах, вы просто передаете другую реализацию зависимости. Вы не привязаны или не связаны с каким-либо одним имплантантом внутри метода doSomethingWith.

но я также прочитал, что если мы объявим объект myObj как MyInterface, myObj не сможет использовать свои собственные методы (из класса Obj), что правильный

Внутренне экземпляры Obj будут по-прежнему иметь полный доступ к API Obj. myObj по-прежнему является Obj, он всегда сможет использовать свои собственные детали реализации.

public interface MyInterface {
    void frob();
}

public class Obj implements MyInterface {

    public void frob() {
        doFrobbing();
    }

    private void doFrobbing() {
        System.out.println("frobbing");
    }

    public static void main(String[] args) {
        MyInterface myObj = new Obj();
        myObj.frob(); // still internally calls doFrobbing()
        ((Obj)myObj).doFrobbing(); // visible only via class reference
    }
}

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

Ответ 2

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

public interface MyInterface {
    String getName();
}

public class Obj implements MyInterface {
    private String getFirstName() {
        return "John";
    }

    private String getLastName() {
        return "Doe";
    }

    @Override
    public String getName() {
        return getFirstName() + " " + getLastName();
    }
}

public class Sec implements MyInterface {
    private String getDate() {
        return new Date().toString();
    }

    @Override
    public String getName() {
        return getDate();
    }
}

В приведенных выше случаях оба Obj и Sec могут вызывать своих частных членов, даже если они не будут отображаться в других классах. Поэтому, когда вы говорите...

MyInterface myObj = new Obj();
MyInterface mySec = new Sec();

... как вы просили в вопросе, хотя верно, что в myObj и mySec единственный видимый метод getName(), их базовая реализация может быть различной.

Ответ 3

Нет никакой разницы. Вы сможете использовать методы MyInterface интерфейса MyInterface только для myObj и mySec. Очевидно, ваш код будет компилироваться только в том случае, если оба Obj и Sec реализуют интерфейс MyInterface.

Ответ 4

MyInterface myObj = new Obj();
MyInterface mySec = new Sec();

Вы объявляете экземпляр MyInterface с именем myObj. Вы инициализируете его новым Obj(); который разрешен компилятором, если Obj реализует MyInterface. myObj может вызывать только методы MyInterface. То же самое для второй строки.

Вот пример кода, который нужно попробовать:

public class Test {

    public static void main(String args[]){
          A a = new A();
          a.say();
          a.a();

          B b = new B();
          b.say();
          b.b();

          I ia = new A();
          ia.say();
          ia.a(); // fail
    }

}

interface i {
    public void say();
}

class A implements i {
    public void say(){
        System.out.println("class A");
    }
    public void a(){
        System.out.println("method a");
    }
}

class B implements i {
    public void say(){
        System.out.println("class B");
    }
    public void b(){
        System.out.println("method b");
    }
}

Ответ 5

В коде, который вы показали, вы никогда не выполняете никаких бросков.

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

Хорошим примером этого являются слушатели в стандартном JDK. Например, PropertyChangeListener. Это интерфейс, который определяет метод, который можно вызвать, когда "свойство изменено". Типичным использованием этого интерфейса является присоединение его к классу, который имеет свойства, и этот класс будет предупреждать этих слушателей, когда одно из его свойств изменилось.

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

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

Ответ 6

MyInterface mi = new Obj();
mi.getInterfaceMethods(); (methods in the MyInterface)

if(mi instanceof Obj) {
     mi.getObjMethods(); (methods in the Obj)
}

Ответ 7

Изменение типа переменной (т.е. ссылки) не изменяет сам объект. Объект всегда может вызывать свои собственные методы, независимо от того, какие типы объявленных переменных являются ссылкой на него.

Ответ 8

Простая аналогия:

Рассмотрим шеф-повара (интерфейс). И есть китайский шеф-повар (классы) и американский шеф-повар (классы). Теперь есть отель, который ищет наем шеф-повара, основанного на некоторых критериях приемлемости, таких как

  • может приготовить не-вегетерианский
  • может готовить vegeterian
  • имеют опыт 5 лет.

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

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

Это просто вопрос определения того, какие навыки (функциональность) ищет отель.

Надеюсь, вы получите эту идею.