interface - java中接口的一点问题
大家讲道理
大家讲道理 2017-04-17 16:22:35
0
5
431
public class Test {
    
    interface Print{
        void printNumber();
    }
    
    public static void work(Print print){
        System.out.println("开始工作,现在打印一个数字");
        print.printNumber();
        System.out.println("结束工作。");
    }
    
    public static void main(String[] args){
        int id = 5678;
        work(new Print() {
            
            @Override
            public void printNumber() {
                //id = 4444;    
                //假如我试图在这里更改id的值,就会报错,why?
                System.out.println(id);
                //没有报错是输出为5678
            }
        });
    }
    
}

我把java学习中遇到的问题归结为以上测试类,如我上面的注释,当我重写接口中的方法时,在重写方法中无法修改id的值,这是为什么呢?

大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全部回覆(5)
伊谢尔伦

你實作這個介面時其實創建了一個內部類,這個內部類別是屬於外部類別的,而不是構造他的方法的,所以他沒法訪問構造他方法裡的非終態變數。
簡單的來說,你再people() 方法裡建立實現Print 接口的內部類,其中使用了id 這個變量,而其實你是在work() 方法裡才調用了Print ,其實這時候已經超出了people () 的訪問範圍,你是沒辦法訪問id 這個變數的。不過Java提供裡一個機制,你可以把id 參數傳入Print 中,實際上這些參數會複製到Print 中,不過為了確保產生歧義,這些參數都是終態的,你沒法修改它(避免你以為修改它就能修改people() 裡的id)。

阿神

我搞錯了。忽略我。 。

阿神

局部內部類別存取局部變量,局部變數應該被設定為final類型。

大家讲道理

匿名內部類別存取外部成類員變數時,成員變數前應該加上final關鍵字

巴扎黑

若試圖定義一個匿名內部類,並想使用在匿名內部類外部定義的一個對象,則編譯器要求外部對象為final
屬性。 --來自 thinking in java 185頁。

理解為:方法內部的匿名內部類別 存取本方法的參數清單及方法內局部變數時,變數應為final。

補充一點,想修改id,可將id宣告為 外部類別 靜態成員變數即可。
public class innerClass {

static int  id = 5678;

interface Print{
    void printNumber();
}

public static void work(Print print){
    System.out.println("开始工作,现在打印一个数字");
    print.printNumber();
    System.out.println("结束工作。");
}

public static void main(String[] args){
    
    work(new Print() {           
        @Override
        public void printNumber() {
            id = 4444;    
            System.out.println(id);
            //没有报错是输出为4444
        }
    });
}

}

內部類別 詳見 程式設計思想 185頁前後。

//: Parcel8.java
// An anonymous inner class that performs
// initialization. A briefer version
// of Parcel5.java.
package c07.innerscopes;

public class Parcel8 {
// Argument must be final to use inside
// anonymous inner class:
public Destination dest(final String dest) {
return new Destination() {
private String label = dest;
public String readLabel() { return label; }
};
}
public static void main(String[] args) {
Parcel8 p = new Parcel8();
Destination d = p.dest("Tanzania");
}
} ///:~

若試圖定義一個匿名內部類,並想使用在匿名內部類外部定義的一個對象,則編譯器要求外部對象為final
屬性。這正是我們將dest()的自變數設為final 的原因。如果忘記這樣做,就會得到一條編譯期出錯提示。
只要自己只是想分配一個字段,上述方法就肯定可行。但如果需要採取一些類似建構器的行動,又該怎樣
操作呢?透過Java 1.1 的實例初始化,我們可以有效地為一個匿名內部類別建立一個建構器:

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!