2013-02-18 91 views
1

我目前正在開發一個項目,其中有大量的繼承自其他類的類繼承其他類等。它可能比應該更復雜,但我是抽象的抽象者。是否可以在ActionScript 3中更改繼承的訪問修飾符?

無論如何,有時我需要改變一個getter/setter從公開到私人。我想這不是真的需要,而是希望切斷子類中預設的事情,但仍然需要在父類中公開訪問。

因此,一個例子是:

Class Base { 
    public function set label(value:String):void{}; 
} 

Class A extends Base {} 

Class B extends A { 
    public function B() { 
     super(); 
     this.label = "stuff"; 
    } 

    override public function set label(value:String):void { 
     //this setter should not be publicly available since the label should not be possible to change in this class 
    } 
} 

目前,我做在這種情況下兩種情況之一:

  1. 覆蓋二傳手什麼也不做,或將其設置爲默認值,它仍然可以更新/渲染/任何
  2. 拋出一個錯誤,說它在該類中不可用

我已經做了一些搜索,一切都似乎指向這是不可能的,但我從來沒有發現它明確表示,這是不可能的。那麼是否可以在繼承的屬性/函數上更改訪問修飾符?

+2

似乎是一個設計問題。如果我使用的是從以前使用過的另一個類繼承的類,那麼我希望基類中的所有信息仍然可以通過擴展它的類來訪問。如果所有突然出現的信息都不存在,我會有點困惑;如果這些信息仍被列爲集體成員,但我沒有回報我的預期,我會感到特別困惑。 – Marty 2013-02-18 02:59:24

+0

@MartyWallace這是非常真實的。這肯定是我的設計中的一個問題,我正在解決這個問題(由於不到一個月的時間來完成2-3個月的工作並削減一些角落),但我仍然好奇這是否可行。 – 2013-02-18 03:03:39

+2

不幸的是,這絕對是不可能的。我搜索了一段時間嘗試和類似的東西像內部設置和公共getter但沒有運氣。 – Marty 2013-02-18 03:06:24

回答

7

這是不可能的,它不應該是,因爲它會導致混淆和不可預知的類層次結構。對於初學者來說,如果你做了這樣的事情,你會打破Liskov Substitution Principle:一個超類應該總是可以被它的派生類替換。如果另一個程序員意外地交換了類型,更改API將明顯阻止 - 並因此可能導致運行時錯誤和/或莫名其妙的故障。

如果你正在建模的類有不同的行爲,會使你「隱藏」一個公開的API方法,你可能不應該爲此使用繼承 - 或者可能以不同的方式。從你所描述的內容來看,我猜想在層次結構的大部分內容中,無論如何,你應該可以使用組合而不是繼承。

+0

這些都非常好。對我而言,這絕對是一個糟糕的設計,但這正是我得到的時間裏我設法拋棄的。這裏發生了什麼是我創建一個組件類,然後它的孩子是「皮膚」(我使用純粹的AS3,而不是Flex或另一個框架來保持重量儘可能人性化)。如果我有更多的時間,我會創建一個基本的皮膚框架來使用,但我正在使用它。無論如何,我認爲你很好地回答了我的問題。謝謝。 – 2013-02-18 03:58:41

1

這是不可能的在評論由馬蒂華萊士。但這並不罕見。

但是,在您使用的替代方法中,屬性所有者是基類&因此,它應該始終知道派生類使用它自己的屬性所做的任何事情。

而不是你砍的我會因此喜歡的東西是這樣的:

public class Base { 
     protected var _isLabelUsable:Boolean = true; 

     public function set label(value:String):void { 
      if (!_isLabelUsable) 
       throw new Error("Access of undefined property label."); 

      // Set Label here 
     } 
    } 

public class A extends Base { 

} 

public class B extends A {  
     public function B() { 
      super();    
      _isLabelUsable = false; 
     }  
    } 
+0

這並不是一個好方法。這樣它就是基類的一個功能。你可以爲'有用'屬性創建一個只讀的getter,以便其他類可以看到它們是否可用。誠實地說,我可以用這種模式來做其他事情。我會避免將它用於此目的(因爲這是一種不好的做法),但它可能在其他地方很有用。 – 2013-02-18 04:01:24

0

這些都是有效分,但是...... 在有些情況下,他們都是無效的情況下。 給定一個來自外部源的基類。就像mx:Panel一樣。 它有屬性'titleIcon:類' 派生類繼承所有屬性和函數。但是使用它的人不能直接設置titleIcon,因爲部分派生類的功能取決於圖標名稱的可用性。它提供了一個屬性iconName:String。設置它也會設置titleIcon。 現在如何防止人們仍然直接設置圖標? UI提供了AS3和MXML的舊屬性,編譯器(當然)不會抱怨。

如果titleIcon是setter/getter對(在這種情況下,它是),而不是final,則派生類可以覆蓋setter並引發錯誤,而iconName setter將圖標類分配給super。 titleIcon。 但是,這是笨拙的,不適用於最終功能或變量。

如果有一種方法,至少告訴用戶界面不再提供財產或顯示警告...