2016年12月10日 星期六

static、default (java8 一)

Eclipse也要設定才行,在專案按右鍵-->Properties後,如下設定


static、default

介面
java7(含)之前:
  屬性:只能是static,且一定要有初始值(沒寫static,預設為public static final)
  一般方法:不能實作,不寫修飾子,預設為 public abstract
  static 方法:static會編譯錯誤

java8:
  屬性:和之前一樣
  一般方法:和之前一樣
  static 方法:可以用了,但一定要實作,所以main方法可以寫在介面裡了

修飾子一定都是public,不打可以,但打就一定要打public,否則會編譯錯誤
java8還出現了一個default關鍵字,只能用在方法,且一定要實作
寫了 default,就不會有隱藏的 abstract 了,而且 default 、abstract、static 只能取其一
defaullt 也可以用泛型方法,定義在 default 關鍵字的右邊

但要注意繼承時,static不會被繼承下去,default可以,如下:

interface I1 {
    default void defaultMethod() {
        System.out.println("i1 default method");
    }
    
    static String sfield = "i1 sfield";
    String field = "i1 field";
    
    static void staticMethod() {
        System.out.println("i1 method");
    }
}
    
interface I2 {
    default void defaultMethod() {
        System.out.println("i2 default method");
    }
    
    static String sfield = "i2 sfield";
    String field = "i2 field";
    
    static void staticMethod() {
        System.out.println("i2 method");
    }
}
    
public class Java8Test implements I2, I1 {
    public static void main(String[] args) {
        Java8Test test = new Java8Test();
        test.defaultMethod();
    }
    
    /*
        @Override
        public void defaultMethod() {
            I2.super.defaultMethod();
        }
    */
}

※I1 和 I2 如果有繼承關係,那麼 Java8Test 就不需要實作,印出來的是子介面

※I1 和 I2 如沒有繼承關係,就要實作其中一個,這樣test.defaultMethod()才知道要呼叫哪一個,如註解的部分



interface I3 extends I1, I2{
    default void defaultMethod(){
        I2.super.defaultMethod();
    }
}
public class Java8Test implements I3 {
    // ...
}

※也可以再寫一支介面,繼承I1和I2,將介面.super.default方法寫在裡面,然後測試類直接繼承新的介面即可,此時I1和I2有無繼承就沒有關係了


※this

上面的程式碼有super,當然也會有this


interface I1 {
    default String i1a() {
        return this.i1b() + this.i1c();
    }
    
    default String i1b() {
        return "call ";
    }
    
    default String i1c() {
        return "success";
    }
}
    
public class Java8Test {
    public static void main(String[] args) {
        I1 i = new I1() {};
        System.out.println(i.i1a());
    }
}

※java7(含)之前,不能new介面,除非用匿名類別
但java8 default的方法已經實作了,所以可以new介面了,但要有「{}」


※覆蓋

interface I1 {
    default String method() {
        return "xxx";
    }
}
    
interface I2 extends I1 {
    default String method() {
        return null;
    }
}
    
interface I3 extends I2 {
    String method();
}
    
public class Java8Test implements I3 {
    public static void main(String[] args) {
        System.out.println(new I1() {}.method());// xxx
        System.out.println(new I2() {}.method());// null
        // System.out.println(new I3() {}.method());// 編譯錯誤
        System.out.println(new Java8Test().method());// ooo
    }
    
    @Override
    public String method() {
        return "ooo";
    }
}

※如果I2沒有覆寫I1的方法,就都會是xxx

※I3還可以將已實作的方法,改成抽象,所以I3又不能new了,解決方法和之前的版本一樣

沒有留言:

張貼留言