将对象强制转换为java中的接口?

时间:2011-12-07 00:29:09

标签: java interface

如果我们将一个对象转换为一个接口,这个对象是不是能够调用自己的方法?在以下示例中,myObj只能调用MyInterface方法?

MyInterface myObj = new Obj();

如果这是正确的,那两个对象之间有什么区别:

MyInterface myObj = new Obj();

MyInterface mySec = new Sec();

感谢您的帮助

8 个答案:

答案 0 :(得分:18)

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

为了使其合法,ObjSec都必须是MyInterface的实施者。这两个对象之间的区别在于 它们提供的实现方式。 ObjSec可以做两件非常不同或非常相似的事情,但他们的共同点是他们会坚持你可以依赖的合同。考虑一下你有一个方法

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

每个对象myObjmySec都可以传递给此方法,然后此方法可以使用该对象的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();
    }
}

在上述情况下,ObjSec都可以调用其私有成员,即使它们在其他类中不可见。所以,当你说...

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

...正如您在问题中提到的那样,虽然在myObjmySec中唯一可见的方法是getName(),但它们的底层实现可能会有所不同。

答案 2 :(得分:1)

没有区别。您只能在MyInterfacemyObj上调用mySec接口方法。显然,只有ObjSec实现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)

一个简单的类比:

考虑一名厨师(接口)。还有中国厨师(班级)和美国厨师(班级)。 现在,有一家酒店希望根据一些资格标准招募厨师,例如

  • 可以煮非素食者
  • 可以烹饪素食者
  • 有5年的经验

此处,资格是评估Chef类型人员的上下文(类型功能)。现在,有些情况下,中国厨师也可以烹制海鲜,意大利菜等。美国同行也是如此。所有这些似乎与酒店经理无关,因为他只关心所需的标准。

在酒店工作的厨师类似于代码中使用的Chef类型对象。显而易见的工作是烹饪素食和非素食(标准或界面方法)。这并不意味着酒店不能利用中国厨师的海鲜制作技巧。

这只是指定酒店正在寻找的技能(功能)。

希望你明白这一点。