前言 :
Scala 是一個可直譯、編譯、靜態、運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. Scala 的繼承作了一些限制,這使你在使用繼承前必須多一份思考.
遮蔽(Shadow)與重新定義(Override) :
所謂遮蔽(Shadow),是指在某變數可視範圍內,定義了同名變數,在後者的可視範圍中,取用同一名稱時所用的是後者的定義。例如 :
- val x = 10
- {
- val x = 20
- println(x) // 顯示 20
- }
- println(x) // 顯示 10
- class A {
- protected int x = 10;
- }
- class B extends A {
- public int x = 20; // 這邊 x 遮蔽了 A 類別中的 x
- }
- public class Main {
- public static void main(String[] args) {
- B b = new B();
- A a = b;
- System.out.println(b.x); // 顯示 20
- System.out.println(a.x); // 顯示 10, 因為是遮蔽, 不是改寫. 所以類別 A 定義的值仍然有效
- }
- }
- class Parent {
- protected val x = 10
- }
- class Child extends Parent {
- val x = 20
- }
- class Parent {
- protected val x = 10
- }
- class Child extends Parent {
- override val x = 20
- }
- val c = new Child
- println(c.x) // 顯示為 20
- class Parent {
- private val x = 10
- }
- class Child extends Parent {
- val x = 20 // 因為 Parent 的 x 在這邊不可視,所以不用 override
- }
- val c = new Child
- println(c.x)
- class Parent {
- val x = 10
- }
- class Child extends Parent {
- override protected val x = 20 // error, value x has weaker access privileges
- }
- ShadowVSOverride.scala 代碼 :
重 新定義成員時,主要是為了避免影響已使用你程式的客戶端。然而宣告為 private[this] 的成員,是完全只能在類別中使用,不可能透過參考名稱來存 取該成員,也就是客戶端完全不可能使用到你宣告為 private[this] 的成員,所以這種情況是允許的,而在這種情況下,例如上例中,Child 中的 x 在類別中,遮蔽了 Parent 的 x,因此透過 getX 取回時會是 20 的值. 另外要注意的是,你不可以重新定義 var 為 val,例如下例通不過編譯
- class Parent {
- var x = 10
- }
- class Child extends Parent {
- override val x = 10 // error, value x cannot override a mutable variable
- }
沒有留言:
張貼留言