1

私は現在、他のクラスから継承する他のクラスなどから継承するクラスがたくさんあるプロジェクトに取り組んでいます。おそらく必要以上に複雑ですが、私は抽象化が苦手です。

とにかく、ゲッター/セッターをパブリックからプライベートに変更する必要がある場合があります。それは実際には必要ではないと思いますが、子クラスに事前設定されているものの、親クラスでパブリックにアクセスできるようにする必要があるものを切り捨てたいという願望です。

したがって、例は次のようになります。

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
    }
}

現在、私はこれらの場合に2つのことのいずれかを行っています:

  1. セッターをオーバーライドして何もしないか、デフォルト値に設定して、更新/レンダリング/何でもできるようにします
  2. そのクラスでは利用できないというエラーをスローします

私はいくつかの検索を行いましたが、すべてがこれが不可能であることを示しているようですが、不可能であると明示的に述べられていることは一度もありません. 継承されたプロパティ/関数のアクセス修飾子を変更することは可能ですか?

4

3 に答える 3

7

それは不可能であり、実際にはそうすべきではありません。それは、混乱を招き、予測不可能なクラス階層につながるからです。手始めに、あなたがそのようなことをした場合、あなたはリスコフの置換原則を破るでしょう:スーパークラスは常にその派生クラスによって置き換え可能でなければなりません。APIを変更すると、明らかにそれが防止されます。したがって、別のプログラマーが誤って型を交換した場合、ランタイムエラーや不可解なグリッチが発生する可能性があります。

モデリングしているクラスの動作が異なり、それ以外の場合はパブリックAPIメソッドを「非表示」にする場合は、おそらくこれに継承を使用しないでください。または、別の方法で使用する必要があります。あなたが説明していることから、階層の大部分では、とにかく、継承ではなく構成を使用する必要があると思います。

于 2013-02-18T03:44:53.793 に答える
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; 
        }       
    }
于 2013-02-18T03:46:52.687 に答える