簡體   English   中英

在Java中將內部接口定義為該類的實例變量

[英]Defining an inner interface in Java as an instance variable to the class

我對正在查看的某些源代碼感到困惑,並且試圖獲得更好的理解。 該代碼在下面,但也可以在Ideone上使用 ,您可以自己使用它。

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone
{
    public interface Fruit {
        public void apple();
    }

    Fruit interfaceFruit;

    public void apple(){
        System.out.println("apple");
        if (interfaceFruit != null) {
            interfaceFruit.apple();
        }
    }

    public void setFruit(Fruit f) {
        interfaceFruit = f;
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        Ideone test = new Ideone(){
            @Override
            public void apple() {
                System.out.println("local override of apple");
            }
        };
        System.out.println("1) ---");
        test.apple();

        Ideone test2 = new Ideone();
        System.out.println("2) ---");
        test2.apple();

        test2.setFruit(new Fruit() {
            @Override
            public void apple() {
                System.out.println("interface override of apple");
            }
        });
        System.out.println("3) ---");
        test2.apple();
    }
}

輸出為:

1) ---
local override of apple
2) ---
apple
3) ---
apple
interface override of apple

這段代碼到底是怎么回事? 在類內部聲明了一個接口(所以是一個內部接口,對嗎?),然后將該接口聲明為該類的實例變量。 這就是我感到困惑的地方。

我認為發生的是,如果為接口Fruit實例化了一個匿名內部類,我們將創建一個實現該接口的未命名類。 我不完全了解接口如何或為什么存儲在類的實例變量中。 這樣做的目的是什么? 這種做法叫什么? 這似乎很奇怪,我不太確定有人會從中得到什么。

這不是通常的代碼,它只是一個練習,因此您可以了解它的工作原理。 是的,事情看起來可能很“奇怪”。

What I'm not totally getting is how or why the interface is stored in an instance variable to the class

它沒有存儲 ,它是定義的 您可以在一個類中定義內部類和接口。 幾個例子:

  • 類和接口僅在類的內部邏輯中使用,而在其他地方則不需要; 通常將這些定義為私有。 與匿名類大致相同。

  • 類和接口與類緊密耦合。 例如,您為該bean定義了一個類和一個Comparator實現。 由於此類Comparator僅對該類的元素有用,因此可以將其定義為嵌套類。 它就像“包裝”的另一個層次一樣。

例如,我擅長控制傳遞給我的方法的值,因此,在有意義的時候,我會做類似的事情(非常愚蠢的示例)

public class Calendar {
   public static enum WeekDay {
     MONDAY,
     ...
     SUNDAY;
  }

  public Date getNextDay(WeekDay weekDay) {
     ...
  }
}

枚舉僅用於訪問類的邏輯,因此在類內定義。

Java API中的示例是java.util.Map.Entry<K,V>類, Map實現使用該類來訪問它們存儲的鍵值對。

聲明:

Fruit interfaceFruit;

簡單地說:“聲明變量interfaceFruit ,它將用於保存對實現Fruit的對象的引用。

如果該變量實現了接口,則可以保存對任何類的引用。 您可以使用它來訪問接口中定義的所有方法和常量,因為Java知道無論該類是什么,它將具有與Fruit的聲明匹配的重載方法(在這種情況下,該聲明僅具有apple() )。

這種事情在Java中非常普遍。 它允許您使用變量來保存符合合同的任何對象,但是可以使用其不同的實現。 這種做法稱為“編程到接口”。 一個非常常見的示例是聲明一個變量,例如:

List<Integer> list;

(其中List是接口java.util.List ),然后為其分配特定的實現:

list = new LinkedList<Integer>();
list = new ArrayList<Integer>();
list = Arrays.asList(1,5,8,9);

無論您將對象分配給哪個類(在Arrays.asList的情況下,您甚至都不知道是哪個類),它將具有java.util.List定義的所有操作-例如add()iterator()

因此,同樣適用於您的Fruit界面。 它恰好是嵌套接口的事實並不那么重要。

暫無
暫無

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

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