如果我们将一个对象转换为一个接口,这个对象是不是能够调用自己的方法?在以下示例中,myObj
只能调用MyInterface方法?
MyInterface myObj = new Obj();
如果这是正确的,那两个对象之间有什么区别:
MyInterface myObj = new Obj();
MyInterface mySec = new Sec();
感谢您的帮助
答案 0 :(得分:18)
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
的实例将继续拥有对Obj
API的完全访问权限。 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
。在外部,通过接口引用使用这些实例的人员只能访问接口方法。
答案 1 :(得分:1)
只有界面中的方法是可见,但是对象中的所有方法仍然可以被调用,只要它们可以访问它们。例如:
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()
,但它们的底层实现可能会有所不同。
答案 2 :(得分:1)
没有区别。您只能在MyInterface
和myObj
上调用mySec
接口方法。显然,只有Obj
和Sec
实现Myinterface
接口时,您的代码才会编译。
答案 3 :(得分:1)
MyInterface myObj = new Obj();
MyInterface mySec = new Sec();
您声明名为myObj的MyInterface的实例。 用新的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");
}
}
答案 4 :(得分:0)
在您展示的代码中,您从不执行任何演员表。
接口的典型用法是定义一些可用的方法,而不关心具体的实现。
一个很好的例子是标准JDK中的监听器。例如PropertyChangeListener
。这是一个接口,它定义了一个可以在“属性被更改”时调用的方法。此接口的典型用法是将其附加到具有属性的类,并且当其中一个属性发生更改时,此类将警告这些侦听器。
班级并不关心那些听众会做什么。它只依赖于这个propertyChange
方法存在的事实,并调用该方法。
该类只能在侦听器上调用此方法,因为它只知道接口中定义的方法。如果那些监听器有其他方法,他们可以自己调用这些方法,但这只是因为他们知道它们不仅仅是接口。
答案 5 :(得分:0)
MyInterface mi = new Obj();
mi.getInterfaceMethods(); (methods in the MyInterface)
if(mi instanceof Obj) {
mi.getObjMethods(); (methods in the Obj)
}
答案 6 :(得分:0)
更改变量的类型(即引用)不会更改对象本身。对象总是可以调用自己的方法,无论声明的变量类型是什么类型的引用。
答案 7 :(得分:0)
一个简单的类比:
考虑一名厨师(接口)。还有中国厨师(班级)和美国厨师(班级)。 现在,有一家酒店希望根据一些资格标准招募厨师,例如
此处,资格是评估Chef类型人员的上下文(类型功能)。现在,有些情况下,中国厨师也可以烹制海鲜,意大利菜等。美国同行也是如此。所有这些似乎与酒店经理无关,因为他只关心所需的标准。
在酒店工作的厨师类似于代码中使用的Chef类型对象。显而易见的工作是烹饪素食和非素食(标准或界面方法)。这并不意味着酒店不能利用中国厨师的海鲜制作技巧。
这只是指定酒店正在寻找的技能(功能)。
希望你明白这一点。