Лить объект в интерфейс в java?
Если мы передадим объект интерфейсу, этот объект не сможет вызвать его собственные методы? в следующем примере myObj
сможет вызывать только методы MyInterface?
MyInterface myObj = new Obj();
Если это правильно, в чем разница между этими двумя объектами:
MyInterface myObj = new Obj();
MyInterface mySec = new Sec();
Спасибо за помощь
Ответы
Ответ 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 (функциональность типов). Теперь могут быть случаи, когда китайский шеф-повар также может готовить морскую пищу, итальянские блюда и т.д., Так может быть и с американским коллегой. Все это может показаться неуместным для менеджера отеля, поскольку он касается только требуемых критериев.
Шеф-повар работает в отеле, аналогичен типу шеф-повара, используемому в коде. Очевидная работа - приготовить вегетерианскую и не-вегетерианскую пищу (критерии или методы интерфейса). Это не означает, что отель не может использовать навыки китайской кухни шеф-повара.
Это просто вопрос определения того, какие навыки (функциональность) ищет отель.
Надеюсь, вы получите эту идею.