【问题标题】:Java cast interface to classJava将接口转换为类
【发布时间】:2011-12-14 02:25:24
【问题描述】:

我有一个关于接口和实现接口的类的问题。

这是我的代码:

interface iMyInterface {
    public iMethod1();
}

public class cMyClass implements iMyInterface {
    public iMethod1() {
        // some code
    }
    protected iMethod2() {
        // some code
    }
}

我想创建一个iMyInterface 的实例,如下所示:

iMyInterface i = new cMyClass();
i.iMethod1();

没关系,但是如何从我的接口实例调用iMethod2()?这是否有效且安全:

((cMyClass)i).iMethod2();

感谢您的帮助。

【问题讨论】:

    标签: java class interface casting


    【解决方案1】:

    还有另一种方法可以将接口转换为类。下面是一个例子。

    interface iMyInterface {
       void iMethod1();
    }
    
    public class cMyClass implements iMyInterface {
    
    private iMyInterface myInterface;
    
    public cMyClass() {
        myInterface = this;
    }
    
    public void iMethod1(){
        System.out.println("Print from cMyClass iMethod1()");
    }
    
    protected void iMethod2() {
        System.out.println("Print from cMyClass iMethod2()");
    }
    
    /**
     * Getter so we can access to the interface methods.
     * @return
     */
    public iMyInterface getMyInterface() {
        return myInterface;
    }
    }
    

    为了从您的界面获取值,这里是代码示例。

    public class Main {
    public static void main(String[] args) {
    
        cMyClass myClass = new cMyClass();
        myClass.getMyInterface().iMethod1();
        myClass.iMethod2();
    }
    }
    

    输出:

    从 cMyClass iMethod1() 打印

    从 cMyClass iMethod2() 打印

    我认为这是一个很好的例子,您可以将接口代码与类代码分开。只需创建接口的实例,并通过该接口的 getter 使用每个方法。

    【讨论】:

      【解决方案2】:

      它会起作用(前提是 cMyClass 实现了 iMyInterface 并且您在 protected 修饰符的范围内)但这不是正确的 OO 方法。

      如果您想使用 iMethod2,请考虑:

      • 将其添加到界面中
      • 创建另一个包含该方法的接口
      • 使用cMyClass myClass = new cMyClass();

      【讨论】:

      • 谢谢,我在界面中添加了Method2。
      【解决方案3】:

      是的,这将起作用(如果您将cMyClass 的声明更改为实现iMyInterface)并且只要引用确实确实 引用cMyClass 的实例,它就是安全的。

      但是,这通常是个坏主意。使用接口的全部意义在于能够与 any 实现一起工作 - 它将抽象与实现分开。如果你接下来需要一个特定的实现,你不妨将 i 的类型设为 cMyClass 开始。

      因此,假设您不是自己调用 cMyClass 构造函数,而是收到一个类型为 iMyInterface 的方法参数 - 此时强制转换为 cMyClass 是个坏主意,因为它可能是一个 不同的 接口的实现。

      (另外说明,开始遵循 Java 命名约定是个好主意,该约定规定类和接口应该是 Pascal 大小写的 - 所以放弃 ci 前缀。)

      【讨论】:

      • 我认为,如果他要投射,他应该使用instanceof 验证投射,以确保安全。
      • @S.L.Barth:当然,除非所需的故障模式是 ClassCastException,否则无条件强制转换是可以的。
      • @Jon Skeet 谢谢,我现在正在使用它,包括界面中的 Method2。抱歉,我忘记在我的示例中添加 implements iMyInterface
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-31
      • 2020-12-06
      相关资源
      最近更新 更多