簡體   English   中英

接口內的內部類

[英]Inner class within Interface

是否可以在接口中創建內部類
如果可能的話,我們為什么要創建這樣的內部類,因為我們不打算創建任何接口對象?

這些內部類對任何開發過程有幫助嗎?

是的,我們可以在接口中使用類。 使用的一個例子可能是

public interface Input
{
    public static class KeyEvent {
         public static final int KEY_DOWN = 0;
         public static final int KEY_UP = 1;
         public int type;
         public int keyCode;
         public char keyChar;
    }
    public static class TouchEvent {
         public static final int TOUCH_DOWN = 0;
         public static final int TOUCH_UP = 1;
         public static final int TOUCH_DRAGGED = 2;
         public int type;
         public int x, y;
         public int pointer;
    }
    public boolean isKeyPressed(int keyCode);
    public boolean isTouchDown(int pointer);
    public int getTouchX(int pointer);
    public int getTouchY(int pointer);
    public float getAccelX();
    public float getAccelY();
    public float getAccelZ();
    public List<KeyEvent> getKeyEvents();
    public List<TouchEvent> getTouchEvents();
}

這里的代碼有兩個嵌套的類,它們用於封裝有關事件對象的信息,這些信息稍后用於方法定義,如 getKeyEvents()。 將它們放在 Input 界面中可以提高凝聚力。

是的,您可以在 Java 接口中創建嵌套類或內部類(請注意,與流行的看法相反,沒有“靜態內部類”這樣的東西:這根本沒有意義,沒有“內部”和“當嵌套類是靜態的時,外部”類,因此它不能是“靜態內部”)。

無論如何,以下編譯正常:

public interface A {
    class B {
    }
}

我已經看到它曾經將某種“合同檢查器”直接放在接口定義中(好吧,在嵌套在接口中的類中,它可以具有靜態方法,而接口本身則不能)。 如果我沒記錯的話,看起來像這樣。

public interface A {
    static class B {
        public static boolean verifyState( A a ) {
            return (true if object implementing class A looks to be in a valid state)
        }
    }
}

請注意,我不是在評論這種東西的用處,我只是在回答你的問題:它可以做到,這是我見過的一種用途。

現在我不會評論這樣一個構造的有用性,並且從我所看到的:我已經看到了它,但它不是一個非常常見的構造。

200KLOC 代碼庫在這里發生的時間恰好為零(但是我們還有很多其他事情,我們認為這些錯誤的做法也恰好在零時間發生,而其他人會認為這是完全正常的……)。

一個有效的用法,恕我直言,是定義由封閉接口方法接收或返回的對象。 通常是數據保存結構。 這樣,如果該對象僅用於該接口,那么您就可以以更具凝聚力的方式擁有事物。

舉例:

interface UserChecker {
   Ticket validateUser(Credentials credentials);

   class Credentials {
      // user and password
   }

   class Ticket {
      // some obscure implementation
   }
}

但無論如何……這只是品味問題。

引用自Java 7 規范

接口可能包含成員類型聲明(第 8.5 節)。

接口中的成員類型聲明是隱式靜態和公共的。 允許冗余指定這些修飾符中的一個或兩個。

不可能在 Java 接口中聲明非靜態類,這對我來說很有意義。

一個有趣的用例是通過內部類為接口方法提供某種默認實現,如下所述: https : //stackoverflow.com/a/3442218/454667 (以克服單類繼承的問題)。

這當然是可能的,我發現它很有用的一種情況是接口必須拋出自定義異常。 您可以將異常與其關聯的接口一起保留,我認為這通常比用一堆瑣碎的異常文件亂扔您的源樹更整潔。

interface MyInterface {

   public static class MyInterfaceException extends Exception {
   }

   void doSomething() throws MyInterfaceException;
}

是的,在接口中可以有靜態類定義,但這個特性最有用的方面可能是使用枚舉類型(這是一種特殊的靜態類)。 例如,你可以有這樣的東西:

public interface User {
    public enum Role {
        ADMIN("administrator"),
        EDITOR("editor"),
        VANILLA("regular user");

        private String description;

        private Role(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }
    }

    public String getName();
    public void setName(String name);
    public Role getRole();
    public void setRole(Role role);
    ...
}

@Bachi 提到的類似於 Scala 中的特征,實際上是使用接口內的嵌套類實現的。 這可以在 Java 中模擬。 另請參閱java 特性或 mixins 模式?

也許當您想要更復雜的結構(例如一些不同的實現行為)時,請考慮:

public interface A {
    public void foo();

    public static class B implements A {
        @Override
        public void foo() {
            System.out.println("B foo");
        }
    }
}

這是您的界面,這將是實施者:

public class C implements A {
    @Override
    public void foo() {
        A.B b = new A.B();
        b.foo(); 
    }

    public static void main(String[] strings) {
        C c = new C();
        c.foo();
    }
}

可能會提供一些靜態實現,但這不會令人困惑,我不知道。

我發現了這種類型的構造的用途。

  1. 您可以使用此構造來定義和分組所有靜態最終常量。
  2. 因為,它是一個接口,您可以在類上實現它。

您可以訪問所有分組的常量; 在這種情況下,類的名稱充當命名空間。

您還可以為實現此接口的對象的通用功能創建“Helper”靜態類:

public interface A {
    static class Helper {
        public static void commonlyUsedMethod( A a ) {
           ...
        }
    }
}

我現在需要一個。 我有一個接口,可以方便地從它的幾個方法返回一個唯一的類。 此類僅作為來自此接口方法的響應的容器才有意義。

因此,有一個靜態嵌套類定義會很方便,它只與這個接口相關聯,因為這個接口應該是唯一創建這個結果容器類的地方。

例如,Groovy 中的特性(類似於具有已實現方法的接口)。 它們被編譯為一個接口,其中包含實現所有方法的內部類。

暫無
暫無

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

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