Java Sealed Classes
Introduction
Java 16推出也兩個月了,照預定進度,(2021年) 9月即將推出Java 17,同時也是LTS。
目前的LTS分別有
- Java 8(最後延伸支援日期為2030 年 12 月)
- Java 11(最後延伸支援日期為2026 年 9 月)
Java 8 目前處於屹立不搖的地位,其中一種原因就是因為最後延伸支援日期。雖然尚未公布,不過可以期待Java 17的最後延伸支援日期,除了必然會晚於Java 11外,也極有可能晚於萬年不敗的Java 8
Sealed Classes 在 Java 15 版本開始發布 Preview(JEP 360),並且在 Java 16 版本發布Second Preview(JEP 397);雖然 Java 17 尚未推出,但也被列為擬定目標(JEP 409)。我們可以提前來看看這個新語法。
Enable preview features
[Eclipse設定]
Eclipse Version: 2021-03 (4.19.0)
目前僅支援到 Java 15,必須先利用 patch方式更新來支援 Java 16
讓我們開啟Eclipse Marketplace,搜尋 'Java 16' 並安裝插件
接著enable preview features : 直接在Project->Properties中設定
Let's try
開始建立第一個Sealed Classes
public abstract sealed class Animal permits Dog,Cat,Bird {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Animal [name=" + name + "]";
}
}
這裡出現了兩個新的關鍵字
- sealed:宣告為密封類,僅允許特定類繼承(extend)
- permits:宣告上述特定類
運用新的特性,上帝創造了嚴謹的動物,也就是狗、貓、以及鳥。世界上再也沒有其他動物。
當繼承Sealed Classes,必須要加入以下關鍵字的其一
- final:老朋友,不允許繼承
- sealed:繼承類同時為密封類,僅允許特定類繼承
- non-sealed:繼承類為非密封類,允許任意類繼承
詳見以下範例
public final class Dog extends Animal {
public Dog() {
this.name = "Dog";
}
}
final 是既有關鍵字,可以設計封閉的繼承樹。
狗,忠誠的狗,老狗,變不出新把戲,就只是隻狗。
public sealed class Cat extends Animal permits PersianCat,AmericanShorthair,Chinchilla {
public Cat() {
this.name = "Cat";
}
}
public final class PersianCat extends Cat {
public PersianCat() {
this.name = "Persian cat";
}
}
// skip
使用 sealed 則可以設計更長的繼承樹,同時更下層的類也需要加入關鍵字final/sealed/non-sealed
任性的貓告訴上帝他要繁衍的子嗣:波斯貓、美短、金吉拉。他們都是貓。
public non-sealed class Bird extends Animal {
public Bird() {
this.name = "Bird";
}
}
public class Bat extends Bird{
public Bat() {
this.name = "Bat";
}
}
使用 non-sealed 則可以解放繼承限制,也就是開放任意類繼承。
鳥類太廣泛了,會飛的蝙蝠也常常被誤認為鳥類?
Summary
在不久的將來,Java 17 上線後,你的商業邏輯也有一些想要限制繼承的需求嗎?一起來更新Java版本,使用新特性吧。