在java中将对象强制转换为接口?
如果我们将一个对象强制转换为接口,这个对象不能调用自己的方法吗?在下面的示例中,将只能调用 MyInterface 方法吗?myObj
MyInterface myObj = new Obj();
如果这是正确的,那么这两个对象之间的区别是什么:
MyInterface myObj = new Obj();
MyInterface mySec = new Sec();
感谢您的帮助
如果我们将一个对象强制转换为接口,这个对象不能调用自己的方法吗?在下面的示例中,将只能调用 MyInterface 方法吗?myObj
MyInterface myObj = new Obj();
如果这是正确的,那么这两个对象之间的区别是什么:
MyInterface myObj = new Obj();
MyInterface mySec = new Sec();
感谢您的帮助
MyInterface myObj = new Obj();
MyInterface mySec = new Sec();
要使这合法化,两者都必须是 的实现者。这两个对象之间的区别在于它们如何提供该实现。 并且可以做两件非常不同或非常相似的事情,但它们的共同点是它们会遵守您可以依赖的合同。考虑你有一个方法Obj
Sec
MyInterface
Obj
Sec
public void doSomethingWith(MyInterface thing) {
thing.frob();
}
每个对象 和 都可以传递到此方法中,然后此方法可以使用该对象的方法(假设 frob 是接口声明的一部分)。这是解放。这允许您通过编程到接口而不是实现来做非常强大的事情。例如,您可以扩展类的功能,而不必更改这些类中的一行代码,只需传递依赖项的不同实现即可。您没有绑定或耦合,该方法中的任何一个暗示。myObj
mySec
frob
doSomethingWith
但我也读到,如果我们将对象myObj声明为MyInterface,myObj将无法使用自己的方法(来自Obj类),这是正确的
在内部,的实例将继续具有对 API 的完全访问权限。 仍然是一个,它将始终能够使用自己的实现细节。Obj
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
只有接口中的方法可见,但对象中的所有方法仍然可以被调用,只要它们以其他方式可访问即可。例如:
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()