如何将抽象类编写为接口

时间:2014-07-01 05:34:54

标签: java class inheritance interface multiple-inheritance

我已经广泛搜索了这个问题的答案,但我要么不知道技术术语是什么,要么就是不可能,所以请原谅我的无知。< / p>


首先是代码,然后是原因背后的理由。

package package1;
public interface MyInterface {
    public ... method1(...);
    public ... method2(...);
    public ... method3(...);
    public ... method4(...);

    public static interface|class DEFAULT extends|implements MyInterface {
        public abstract ... method1(...);

        public ... method2(...) {
            // code
        }

        public ... method3(...) {
            // code
        }

        public abstract ... method4(...);
    }
}

现在通常我会抽象一个类来实现MyInterface,但在这种情况下,我不能,因为Java(可以理解)不支持来自多个类的类继承(尽管接口可以扩展多个其他接口)。 / p>

我的(理想的)用例将类似于:

package package3;
import package1.MyInterface;
import package2.SomeBaseClass;
public class MyClass extends SomeBaseClass implements MyInterface.DEFAULT {
    // other class code

    public ... method1(...) {
        // code
    }

    public ... method4(...) {
        // code
    }
}

我可能想出一些解决方法,但我想知道是否有一种更容易/更优雅的方式来做这件事,然后我花了大量时间编写可能最终被我没有的东西排除在外的代码。想到了。


编辑:我应该指定每个类/接口来自不同的包(上面的代码已被修改以反映这种区别)。基本上我将两个软件包的功能合并到第三个软件包中。


编辑:我已经提出了以下内容,我相信这些内容符合解决方案\建议通过撰写来完成此

package MyPackage;

import package1.SomeBaseClass;
import package2.MyInterface;

public class MyClass extends SomeBaseClass {
    private .. someVariable;

    private MyInterface myInterface = new MyInterface.DEFAULT() {
        public ... method1(...) {
            // do something with someVariable
        }

        public ... method4(...) {
            // code
        }
    };

    public void doSomethingThatRequiresMyInterface() {
        myInterface.method1(...);
    }
}

我是否正确理解了这一点?

3 个答案:

答案 0 :(得分:1)

如果你正在使用/可以使用Java 8'默认方法'可能就是你想要的 - &gt; http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

但是,我认为你与上面列出的代码没有什么不同。

MyInterface.java

    public interface MyInterface {
        public ... method1(...);
        public ... method2(...);
        public ... method3(...);
        public ... method4(...);
    }

Default.java

public abstract class Default implements MyInterface {
    public abstract ... method1(...);

    public ... method2(...) {
        // code
    }

    public ... method3(...) {
        // code
    }

    public abstract ... method4(...);
}

SomeBaseClass.java

public abstract class SomeBaseClass extends Default {
    public void someNewMethod();
}

MyClass.java

public class MyClass extends SomeBaseClass {
    // other class code

    @Override
    public ... method1(...) {
        // code
    }

    @Override
    public ... method4(...) {
        // code
    }
}

答案 1 :(得分:0)

如果我理解你的要求,我认为Java 8中引入的新默认方法(也称为防御方法)可以帮助你(tutorial at Oracle)。

它们允许为接口方法定义默认行为,因此实现它们的类不必复制此默认行为(如果足够的话)。

它的引入主要是为了让Java开发团队可以向API接口添加新方法,而不会破坏实现这些接口的现有代码。

示例:

界面:

public interface MyInterface {
    default void method1(String arg1, Object arg2){
        //code...
    }

    default String method2(){
        //code...
    }

    String method3();
}

实施班:

public class MyClass implements MyInterface {

    private String field1;

    public String method3(){
        //code...
    }

    public void someOtherMethod(){
        //code...
    }
}

在这种情况下,实现类没有实现标记为default的接口方法,因此仍然可以调用它们并使用默认实现。但是,它仍然必须实现接口中没有默认实现的method3

但是有一些限制和警告,其中一些列在this blog article中,所以要小心。

顺便说一句:您不必在Java中为interfaces方法指定“public”访问器,因为它已经是默认值,

答案 2 :(得分:0)

您可以使用组合,在其中创建实现接口的类,并提供默认功能,然后将默认实现的实例传递给具体类。如果具体类不提供该功能,请调用默认实例实现的版本。

接口:

public interface Foo {

    int method1(int a, String b);

    String method2(int a);

    String method3(String b);

}

默认实施:

public class DefaultFoo implements Foo {

    @Override
    public int method1(int a, String b) {
        return a + b.length();
    }

    @Override
    public String method2(int a) {
        return a;
    }

    @Override
    public String method3(String b) {
        return b;
    }

}

具体实施:

public class GreenFoo implements Foo {

    Foo defaultFoo = new DefaultFoo();

    @Override
    public int method1(int a, String b) {
        return "Green " + a + ", Mean" + b;
    }

    @Override
    public int method2(int a) {
        return a*a;
    }

    @Override
    public int method3(Sting b) {
        // I don't want to implement this, so I just call the default.
        return defaultFoo.method3(b);
    }

}