05_Java物件導向(三)

Huang Po-Hsuan

105.07.16

只整理易出錯或小重點,並非教學

final 修飾字

類似 c/c++ 的 const (在 Java 裡為無意義修飾字

final 屬性宣告時不一定要給初始值,一旦給了初始值就不可更改

final 方法不可 overriding

public class FinalTest {
    public static void main(String[] args){
        Son son = new Son();
        son.showMoney();
        son.showMoney(1);
    }
}
class Father{
    private final int money;//宣告時不一定要給初始值
    public Father(){
        money = 100;
//        money += 10;//final 一旦給了初始值就不可更改,會Error
    }
    public final void showMoney(){
        System.out.println("father's money = $" + money);
    }
}
class Son extends Father{
    private final int money = 10;
//    public final void showMoney(){}//final 的方法不可 overriding,會Error
    public final void showMoney(int money){//final 的方法可 overloading
        System.out.println("son's money = $" + (this.money + money));
    }
}
run:
father's money = $100
son's money = $11

abstract 抽象修飾字

方法限定

UML 中以斜體表示

後方不可加上 {},而是在 ) 後直接以 ; 結束

Interface (介面) 範例一

+on():void

+off():void

腳踏車

公車

+on():void

+off():void

腳踏車

公車

電燈

怪怪der ?

正確版

腳踏車

公車

電燈

<<interface>>

開關

+on():void

+off():void

介面 UML 表示

public class InterfaceTest {
    public static void main(String[] args){
        車 bike = new 腳踏車();
        車 bus = new 公車();
        電燈 electricLight = new 電燈();
        bike.on();
        bike.off();
        bus.on();
        bus.off();
        electricLight.on();
        electricLight.off();
    }
}
interface 開關{
    public abstract void on();//加上{}會 Error
    void off();//public abstract 可不寫
}
class 車 implements 開關{
    @Override
    public void on(){
        System.out.println("發動");
    }
    @Override
    public void off(){
        System.out.println("熄火");
    }
}
class 腳踏車 extends 車{}
class 公車 extends 車{}
class 電燈 implements 開關{
        @Override
    public void on(){
        System.out.println("開燈");
    }
    @Override
    public void off(){
        System.out.println("關燈");
    }
}
run:
發動
熄火
發動
熄火
開燈
關燈

Interface (介面) 範例二

public class InterfaceTest2 {
    public static void main(String[] args){
        bird b1 = new bird();
        superMan s1 = new superMan();
        b1.fly();
        s1.fly();
    }
}
interface flyer{//鳥、超人都有飛行的功能
    void fly();
}
class bird implements flyer{
    @Override
    public void fly(){//public 必加
        System.out.println("Bird is flying.");
    }
}
class superMan implements flyer{
    @Override
    public void fly(){
        System.out.println("Super man is flying.");
    }
}
run:
Bird is flying.
Super man is flying.

Interface (介面) 補充

介面裡的方法編譯器會自動加上 public abstract

屬性則會加上 public static final

abstract 的方法不可以實作,即沒有 {}

因為沒有實作所以不可以 new

建議在介面的命名前加上 I (大寫 i )增加辨識度

介面支援多重繼承 ex:(下面)

public class MultipleTest {
    public static void main(String[] args){
        
    }
}
interface I1{}
interface I2{}
interface I3{}
interface I4{}
interface I5 extends I1, I2, I3, I4{}
class C1{}
class C2{}
class C3{}
class C4{}
//class C5 extends C1, C2{}//會 Error
//class C5 extends I1{}//會 Error
class C5 implements I1, I2, I3, I4{}//同implements I5
class C6 extends C1 implements I1, I2{}

抽象類別

語法:[存取] abstract class 名稱 [extends ...] [implements ...]

跟介面類別的實作有點類似

因為一樣有 abstract 所以不能 new

抽象類別的方法:

    不一定要用 abstract ,也可完全沒有

    若是 abstract 的方法不可用 static、private 修飾

public class AbstractTest {
    public static void main(String[] args){
        //交通工具 transportation = new 交通工具();//抽象類別不可 new
        交通工具 car = new 車();
        car.移動();
        car.獲取輪胎數();
    }
}
abstract class 交通工具{
    private int 輪胎 = 0;
    void 移動(){//可不為 abstract
        System.out.println("交通工具移動....");
    }
    abstract void 獲取輪胎數();//不可為private、static,不可加上{}
}
class 車 extends 交通工具{
    private int 輪胎 = 4;
    @Override
    void 移動(){
        System.out.println("車移動....");
    }
    @Override
    void 獲取輪胎數(){
        System.out.println("輪胎數:"+輪胎);
    }
}

<<abstract>>

交通工具

-移動():void

~獲取輪胎數():void

-移動():void

~獲取輪胎數():void

抽象類別 UML 表示

run:
車移動....
輪胎數:4

介面類別 V.S. 抽象類別

簡單來說:

若你真的需要繼承某class

但又希望別人無法new它

就將它宣告成 abstract


若你沒有需要繼承某 class

只希望N個 class 都要求有某些功能

就先宣告一個 interface

讓各class去實作它

enum (列舉)

又是一種類別(class) @@

自動 extends Enum

亦可寫在類別內當成內部類別使用

語法:[存取] enum 名稱{內容1,內容2}

若為內部 enum 類別會自動加上 ststic final,非內部則僅 final

ctor 和一些方法會自行產生(下面)

所有內容會加上 public static final 修飾

可用於 switch

這部分有點複雜,本人尚未參透請見諒@@

//ctor 統一長這樣:
private 名稱(String s, int i){
    super(s, i);
}
//而
public static final 名稱[] values(){}
//和
public static 名稱 valueOf(String s){}
//亦會自動產生,長相就請參考其他資料

補充

所以全部要寫的就只有列舉的宣告而已

再補充

列舉可以用 implements 來實作介面

 

 

 

 

任何皆不可 extends Enum or 自訂列舉,由編譯器給定

public class MyClass extends Enum {}
public class MyClass extends Myenum {}
public enum Myenum2 extneds Myenum {}
public enum Myenum2 extends Enum {}
public enum Myenum implements MyInterface {}
public class EnumTest {
    enum Week{//列舉宣告,因為是內部所以會加上 static final
        Sunday,Monday,Tuesday,Wednesday,Thursday,
        Friday{//匿名內部類別方式覆寫 toString()
            @Override
            public String toString(){return "Friday!!!!";}
        },Saturday
    }
    public static void main(String[] args){
        System.out.println(Week.Sunday);
        
        Week week = Week.Monday;
        System.out.println(week);
        
        System.out.println(Week.valueOf("Tuesday"));//.valueOf 回傳一個列舉
        
        System.out.println(Week.valueOf(Week.class, "Wednesday"));//Enum 中的方法,功能同上
        
        switch(Week.Thursday){//支援 switch
            case Monday:break;
            case Thursday:
                System.out.println("Thursday");
        }
        
        System.out.println(Week.Friday);
        
        Week[] weekArray = Week.values();//.values() 回傳列舉內容的陣列
        for(Week w:weekArray){//走訪
            System.out.print(w+" ");
        }
        System.out.println();
    }
}
run:
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday!!!!
Sunday Monday Tuesday Wednesday Thursday Friday!!!! Saturday 

import static

跟 import 差別:

import:只能寫到類別

import static:可寫到靜態成員( static 方法 or 屬性)

                       也可寫到內部列舉(本來就是 static )

 

皆可用萬用字元(*)來寫

不可直接用import static 取代 import

因為不一定有靜態

import java.lang.System;//其實這行會自動被 import,System 是類別

public class ImportStaticTest {
    public static void main(String[] args){
        System.out.println("Hello World");
    }
}
import static java.lang.System.out;//out 是靜態成員

public class ImportStaticTest2 {
    public static void main(String[] args){
        out.println("Hello World");//不必寫 System
    }
}

import

import static

內部類別

Initializer

05_Java物件導向(三)

By aben20807

05_Java物件導向(三)

  • 171