[Kotlin] 實作練習: 建構子(Constructor), 靜態變數(Static Variable), 繼承(Inherit), 覆寫(Override), switch(Java) & when(Kotlin)

用題目來練習會對一個新語言更快進入狀況

對筆者來說,相較於Java,Kotlin是很新的語言,這裡用一個題目同時練習Java與Kotlin的部分

 

郵局有兩種便利箱:
Box3: 長23,寬14,高13 (cm)
Box5: 長39.5,寬27.5,高23 (cm)

1. 請利用物件導向的類別設計這兩個類別,並在這兩個類別(Box3與Box5)中設計方法:
public boolean validate(float length, float width, int height) {

}
並在這方法中設計會回傳(boolean)該箱子是否能容納傳入的長、寬、高的物體。

2. 建立BoxTester類別,程式的main方法中設計讓使用者輸入他想寄送物件的長寬高,並利用Box5與Box3兩個類別完成以下的設計:
Please enter object's length: 15
Please enter object's width: 18
Please enter object's height: 10
Box5

Please enter object's length: 20
Please enter object's width: 11
Please enter object's height: 9
Box3

 

解析

下表為類別圖,Box3為父類別,定義了郵局便利箱的成員和方法;Box5繼承Box3,差別在跟Box3盒子大小不同,因此重新定義盒子的靜態長寬高成員,以及覆寫validate的方法。

設計SizeException類別處理當盒子長寬高的尺寸小於零或等於零的狀況。

詳細程式碼可以參考後面的部分。

建構子(Constructor)

Kotlin的建構子可以在類別定義時一起定義建構子,為主要建構子

class Box5(var length: Float, var width: Float, var height: Int){}

 

也可以像Java一樣設計兩個以上的建構子,Java的次要建構子是用類別的名稱作為建構子的名字

而Kotlin的次要建構子使用constructor作為建構子的名字

class Box3() {
    constructor(length: Float, width: Float, height: Int) : this() {
        /*建構子內容*/
    }
}

 

靜態變數(Static Variable) & 靜態方法(Static Function)

Kotlin處理靜態成員和靜態方法,使用關鍵字companion object

companion object {
    //成員
    //方法
}

 

繼承(Inherit)

Kotlin的類別都是final,預設無法被繼承,所以要被繼承的類別前面要加上關鍵字open

子類別繼承的父類別寫在冒號(:)之後

open class Box3() {}

class Box5(var length: Float, var width: Float, var height: Int): Box3(length, width, height) {}

 

覆寫(Override)

Kotlin的方法都是final,預設無法被覆寫,所以必須在要被覆寫的方法前面加上關鍵字open

覆寫的方法前面加上關鍵字override

open class Box3() {
    open fun validate() =
        (length < LENGTH && width < WIDTH && height < HEIGHT)
}

class Box5(var length: Float, var width: Float, var height: Int): Box3(length, width, height) {
    override fun validate() =
        (length < LENGTH && width < WIDTH && height < HEIGHT)
}

 

 switch(Java) & when(Kotlin)

Java

int number = xxxfunction;

switch (number) {
    case 3:
    	/*...*/
        break;
    case 5:
        /*...*/
        break;
    default:
        /*...*/
}

 

Kotlin

var number = xxxfunction;

when(number) {
    3 -> {
    	/*...*/
    }
    5 -> {
    	/*...*/
    }
    else -> {
    	/*...*/
    }
}

 

Java實作

Box3.java

public class Box3 {
    private float length;
    private float width;
    private int height;

    private static float LENGTH = 23f;
    private static float WIDTH = 14f;
    private static int HEIGHT = 13;

    public Box3(float length, float width, int height) throws SizeException {
        if (length > 0 && width > 0 && height > 0) {
            this.length = length;
            this.width = width;
            this.height = height;
        } else {
            throw new SizeException();
        }
    }

    public boolean validate(float length, float width, int height) {
        if (length < LENGTH && width < WIDTH && height < HEIGHT) {
            return true;
        } else {
            return false;
        }
    }

}

 

Box5.java

public class Box5 extends Box3 {

    private static float LENGTH = 39.5f;
    private static float WIDTH = 27.5f;
    private static int HEIGHT = 23;

    public Box5(float length, float width, int height) throws SizeException {
        super(length, width, height);
    }

    @Override
    public boolean validate(float length, float width, int height) {
        if (length < LENGTH && width < WIDTH && height < HEIGHT) {
            return true;
        } else {
            return false;
        }
    }
}

 

SizeException.java

public class SizeException extends Exception {

    @Override
    public String getMessage() {
        return "Need to set values > 0";
    }

    public SizeException() {
        System.err.println("Need to set values > 0");
    }
}

 

BoxTester.java

import javax.swing.*;

public class BoxTester {
    public static void main(String[] args) {
        Box3 box3 = null;
        Box5 box5 = null;
        int number = 0;

        while (number != -1) {
            String numberStr = JOptionPane.showInputDialog("If you input -1, it will close the program.\n" +
                    "Please choose box.\nBox3: input 3.\nBox5: input 5");
            number = Integer.parseInt(numberStr);
            if (number != -1) {
                String lengthStr = JOptionPane.showInputDialog("Please enter object's length:");
                float length = Float.parseFloat(lengthStr);

                String widthStr = JOptionPane.showInputDialog("Please enter object's width:");
                float width = Float.parseFloat(widthStr);

                String heightStr = JOptionPane.showInputDialog("Please enter object's height:");
                int height = Integer.parseInt(heightStr);

                switch (number) {
                    case 3:
                        try {
                            box3 = new Box3(length, width, height);
                        } catch (SizeException e) {
                            e.getMessage();
                        }
                        JOptionPane.showMessageDialog(null,
                                "Things could place in the box3:"
                                + box3.validate(length, width, height));
                        break;
                    case 5:
                        try {
                            box5 = new Box5(length, width, height);
                        } catch (SizeException e) {
                            e.getMessage();
                        }
                        JOptionPane.showMessageDialog(null,
                                "Things could place in the box5:"
                                + box5.validate(length, width, height));
                        break;
                    default:
                        JOptionPane.showMessageDialog(null,
                                "Please select the right box.");
                }
            }
        }

    }
}

 

Kotlin實作

BoxTester.kt

fun main() {
    var box3: Box3
    var box5: Box5
    var number = 0
    val scanner = Scanner(System.`in`)
    var length: Float
    var width: Float
    var height: Int

    while (number != -1) {
        println("If you input -1, it will close the program.\n" +
                "Please choose box.\nBox3: input 3.\nBox5: input 5")
        number = scanner.nextInt()

        if (number != -1) {
            println("Please enter object's length:")
            length = scanner.nextFloat()
            println("Please enter object's width:")
            width = scanner.nextFloat()
            println("Please enter object's height:")
            height = scanner.nextInt()

            when(number) {
                3 -> {
                    box3 = Box3(length, width, height)
                    println("Things could place in the box3:" + box3.validate())
                }
                5 -> {
                    box5 = Box5(length, width, height)
                    println("Things could place in the box5:" + box5.validate())
                }
                else -> println("Please select the right box.")
            }

        }

    }


}


open class Box3() {
    private var length = 0.0f
    private var width = 0.0f
    private var height = 0

    constructor(length: Float, width: Float, height: Int) : this() {
        if(length > 0 && width > 0 && height > 0) {
            this.length = length
            this.width = width
            this.height = height
        } else throw SizeException()
    }

    companion object {
        const val LENGTH = 23f
        const val WIDTH = 14f
        const val HEIGHT = 13
    }

    open fun validate() =
        (length < LENGTH && width < WIDTH && height < HEIGHT)

}


class Box5(var length: Float, var width: Float, var height: Int): Box3(length, width, height) {

    companion object {
        const val LENGTH = 39.5f
        const val WIDTH = 27.5f
        const val HEIGHT = 23
    }

    override fun validate() =
        (length < LENGTH && width < WIDTH && height < HEIGHT)

}