簡體   English   中英

如何編寫一個抽象類作為接口

[英]How to write an abstract class as an interface

我已經在Google上廣泛搜索該問題的答案,但是我或者不知道該術語是什么,否則就不可能,因此請原諒我的任何無知。


首先是代碼,然后是原因。

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(可以理解)不支持從多個類繼承類(盡管接口可以擴展多個其他接口)。

我的(理想)用例應遵循以下原則:

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(...);
    }
}

我理解正確嗎?

如果您正在使用/可以使用Java 8,則“默認方法”可能就是您要尋找的-> 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
    }
}

如果我很了解您的需求,那么我認為Java 8中引入的新默認方法(也稱為防御者方法)可以為您提供幫助( 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

盡管有一些限制和警告,但在本博客文章中列出了其中的一些限制,請務必小心。

順便說一句:您不必為Java中的接口方法指定“公共”訪問器,因為它已經是默認的,

您可以使用組合,在其中您將創建一個實現該接口並提供默認功能的類,然后將默認實現的一個實例傳遞給具體的類。 如果具體類不提供功能,請調用默認實例實現的版本。

接口:

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);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM