用題目來練習會對一個新語言更快進入狀況
對筆者來說,相較於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類別處理當盒子長寬高的尺寸小於零或等於零的狀況。
詳細程式碼可以參考後面的部分。
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() {
/*建構子內容*/
}
}
Kotlin處理靜態成員和靜態方法,使用關鍵字companion object
companion object {
//成員
//方法
}
Kotlin的類別都是final,預設無法被繼承,所以要被繼承的類別前面要加上關鍵字open
子類別繼承的父類別寫在冒號(:)之後
open class Box3() {}
class Box5(var length: Float, var width: Float, var height: Int): Box3(length, width, height) {}
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)
}
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)
}