04_Java物件導向(二)

Huang Po-Hsuan

105.07.21

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

Overloading (多載)

方法的名稱相同;參數型別 or 數量 or 順序不同

<注意> 不包含方法的回傳型別

public class OverloadingTest {
    public static void main(String[] args){
        Ball ball1 = new Ball();
        System.out.println("ball1 radius = "+ball1.getRadius());
        System.out.println("ball1 color = "+ball1.getColor()+'\n');
        
        Ball ball2 = new Ball(8.7, "red");//ctor overloading可吃不同參數
        System.out.println("ball2 radius = "+ball2.getRadius());
        System.out.println("ball2 color = "+ball2.getColor()+'\n');
        
        Ball ball3 = new Ball("blue", 4.4);//ctor overloading可吃不同參數
        System.out.println("ball3 radius = "+ball3.getRadius());
        System.out.println("ball3 color = "+ball3.getColor());
    }
}
class Ball{
    private double _radius;
    private String _color;
    public Ball(){
        setRadius(1.0);
        setColor("white");
    }
    public Ball(double init_radius, String init_color){//overloading
        setRadius(init_radius);
        setColor(init_color);
    }
    public Ball(String init_color, double init_radius){//overloading
        this(init_radius, init_color);//呼叫ctor,而不是再寫一遍,this用法在後面
    }
    public void setRadius(double set_radius){
        _radius = set_radius;
    }
    public double getRadius(){
        return _radius;
    }
    public void setColor(String set_color){
        _color = set_color;
    }
    public String getColor(){
        return _color;
    }
}

 

字有點小@@

run:
ball1 radius = 1.0
ball1 color = white

ball2 radius = 8.7
ball2 color = red

ball3 radius = 4.4
ball3 color = blue

Overriding (覆寫)

必建立在繼承

方法名稱參數列回傳型別完全與父類別相同

存取修飾不小於父類別的方法

public > protected > package > private

public class OverridingTest {
    public static void main(String[] args){
        人 man1 = new 超人();
        man1.move();
        人 man2 = new 有錢人();
        man2.move();
    }
}
class 人{
    public void move(){
        System.out.println("走路....");
    }
}
class 超人 extends 人{
    @Override
    public void move(){
        System.out.println("飛行....");
    }
}
class 有錢人 extends 人{
    @Override
    public void move(){
        System.out.println("開跑車....");
    }
}
run:
飛行....
開跑車....

遮蔽 (屬性的覆寫)

public class MemberOverridingTest {
    public static void main(String[] args){
        汽車 car = new 六輪跑車();
        System.out.println("六輪跑車輪胎數 = "+car.get輪胎數());
    }
}
class 汽車{
    private int 輪胎數 = 4;
    public int get輪胎數(){
        return 輪胎數;
    }
}
class 六輪跑車 extends 汽車{
    private int 輪胎數 = 6;//覆寫父類別的屬性
    @Override
    public int get輪胎數(){
        return 輪胎數;
    }
}
run:
六輪跑車輪胎數 = 6

this

  • 編譯時期自動加入
  • 是目前正在操作的物件
  • 所以可以用來操作其屬性、方法、ctor
  • 只能在方法ctor 中使用
  • 使用 this 呼叫 ctor 在 overloading 的範例裡有

static成員沒有

public class ThisTest {
    public static void main(String[] args){
        Account acc1 = new Account(10);
        System.out.println("帳戶裡有"+acc1.getMoney()+"元");
    }
}
class Account{
    private int money;
    Account(int money){
        setMoney(money);
    }
    public void setMoney(int money){
        money = money;
    }
    public int getMoney(){
        return money;
    }
}

this 錯誤示範

你以為跑完會顯示10元,那就錯了

run:
帳戶裡有0元

呢?@@

this 正確示範

public class ThisTest {
    public static void main(String[] args){
        Account acc1 = new Account(10);
        System.out.println("帳戶裡有"+acc1.getMoney()+"元");
    }
}
class Account{
    private int money;
    Account(int money){
        this.setMoney(money);//此 this 可寫可不寫
    }
    public void setMoney(int money){
        this.money = money;//主要問題在這裡
        //因為變數名稱都是 money 編譯器認不出來
        //所以要用this.明確表示是物件裡的 money
    }
    public int getMoney(){
        return this.money;//此 this 可寫可不寫
    }
}
run:
帳戶裡有10元

super

  • 編譯時期自動加入
  • 是目前正在操作的物件的父物件
  • 一定要有繼承出現
  • 操作與使用同 this

static成員沒有

public class SuperTest {
    public static void main(String[] args){
        人 man1 = new 超人();
        man1.move();
    }
}
class 人{
    public void move(){
        System.out.println("走路....");
    }
}
class 超人 extends 人{
    @Override
    public void move(){
        super.move();//先執行父物件的 move()
        System.out.println("飛行....");
    }
}
run:
走路....
飛行....

Polymorphism (多型)

呼叫方法時可以直接用到對應的方法

可以用陣列來收集

深層意義在於權限的概念

以下有幾個範例

instanceof 補充

若類別可以轉型會回傳 true,反之回傳 false

語法:變數 instansof 是否可轉型的類別名稱

範例一

public class PolymorphismTest {
    public static void main(String[] args){
        動物 list[] = new 動物[2];//收集
        list[0] = new 狗();
        list[1] = new 雞();
        list[0].叫();
        list[1].叫();
        for(動物 i:list){//走訪
            i.叫();
        }
    }
}
class 動物{
    public void 叫(){}
}
class 狗 extends 動物{
    @Override
    public void 叫(){
        System.out.println("吠叫");
    }
}
class 雞 extends 動物{
    @Override
    public void 叫(){
        System.out.println("啼叫");
    }
}

動物

+叫()

+叫()

+叫()

run:
吠叫
啼叫
吠叫
啼叫

範例二

又不是所有動物都會叫

動物

+叫()

+叫()

public class PolymorphismTest {
    public static void main(String[] args){
        動物 list[] = new 動物[3];//收集
        list[0] = new 狗();
        list[1] = new 雞();
        list[2] = new 魚();
        for(動物 i:list){//走訪
//            i.叫();//直接呼叫會 Error,因為"動物"無"叫()"
            if(i instanceof 狗){//強制轉型前要問是否可以轉
                ((狗)i).叫();//利用強制轉型
            }
            else if(i instanceof 雞){
                ((雞)i).叫();
            }
            else{
                System.out.println("不會叫");
            }
        }
    }
}
class 動物{}
class 狗 extends 動物{
    public void 叫(){
        System.out.println("吠叫");
    }
}
class 雞 extends 動物{
    public void 叫(){
        System.out.println("啼叫");
    }
}
class 魚 extends 動物{}
run:
吠叫
啼叫
不會叫

改善多型的實作

class 交通工具 {
    public void 功能(){}
}
class 車 extends 交通工具{
    @Override
    public void 功能(){
        System.out.println("可以載人");
    }
}
class 跑車 extends 車{
    @Override
    public void 功能(){
        super.功能();
        System.out.println("超快");
    }
}
class 公車 extends 車{
    @Override
    public void 功能(){
        super.功能();
        System.out.println("很多人");
    }
}
class 飛機 extends 交通工具{
    @Override
    public void 功能(){
        System.out.println("飛飛飛");
    }
}

交通工具

+功能()

+功能()

飛機

+功能()

跑車

+功能()

公車

+功能()

public class ImproveImplementTest1 {
    public static void main(String[] args){
        車 car = new 車();
        跑車 sportsCar = new 跑車();
        公車 bus = new 公車();
        飛機 plane = new 飛機();
        get功能(car);
        get功能(sportsCar);
        get功能(bus);
        get功能(plane);
    }
    public static void get功能(車 i){
        i.功能();
        System.out.print('\n');
    }
    public static void get功能(跑車 i){
        i.功能();
        System.out.print('\n');
    }
    public static void get功能(公車 i){
        i.功能();
        System.out.print('\n');
    }
    public static void get功能(飛機 i){
        i.功能();
        System.out.print('\n');
    }
}
run:
可以載人

可以載人
超快

可以載人
很多人

飛飛飛
public class ImproveImplementTest2 {
    public static void main(String[] args){
        車 car = new 車();//型別也可以改為 交通工具
        跑車 sportsCar = new 跑車();
        公車 bus = new 公車();
        飛機 plane = new 飛機();
        get功能(car);
        get功能(sportsCar);
        get功能(bus);
        get功能(plane);
    }
    public static void get功能(交通工具 i){
        i.功能();
        System.out.print('\n');
    }
}
run:
可以載人

可以載人
超快

可以載人
很多人

飛飛飛

改善後,少很多字吧OuO