クラス内の変数と関数のアクセシビリティ

私は2つの質問がありますが、それらは同じ(似たような)問題です。

最初の質問:

public class A {

    public void myProcedure() {
        doSomethingA();
    }

    private void doSomethingA() {}

}

public class B extends A {

    @Override
    public void myProcedure() {
        doSomethingB();
       //IT DOESN'T CALL super.myProcedure
    }

    private void doSomethingB() {}

}

public class C extends B {

    @Override
    public void myProcedure() {
       //I need to execute A's myProcedure here
    }

}

doSomethingApublic に設定せずに AmyProcedure を実行する方法は?

2番目の質問:

私自身の TextBox を作成すると、 myValue という名前の変数があります。 TextBox を継承する AdvancedTextBox を作成し、 myTextBox 変数にアクセスする必要があります。問題は、将来の開発者が TextBoxAdvancedTextBox の両方を使用したい、または myValue にアクセスできないということです。出来ますか?

EDIT: Oli Charlesworth and NullUserException ఠ_ఠ tell me to let C inherit A directly (first question). However, there's some cases this can be disaster. For example: A = TextBox, B = AdvancedTextBox, C = NumberAdvancedTextBox, if C inherits A, so C have to do everything that B does again, with some small changes.

0
@OliCharlesworth私は自分の質問を編集しました(最後に情報を追加します)。ケースCはAから直接継承するべきではないことを伝えます。
追加された 著者 Luke Vo,
まず、プライベートではなく、保護してください。
追加された 著者 corsiKa,
@OliCharlesworthに同意します。 CからAのメソッドにアクセスする必要がある場合は、おそらくCはAから直接継承する必要があります。
追加された 著者 NullUserException,
置換原則により、 C タイプのオブジェクトは次のように動作するはずです B の特殊化です。 A の振る舞いに振舞いを「回帰」させる必要がある場合は、階層が正しくないことを意味します。
追加された 著者 Oliver Charlesworth,
代替元本に関するオリーの指摘は依然として立っている。 NumberAdvancedTextBoxをAdvancedTextBoxの代わりに使用できず、まったく同じ動作をすることができない場合は、プリンシパルを遵守していません。下のHoymkotの答えは鍵の構成を保持している!!!私は、プログラマーが継承で心を動かすことから生まれた非常に多くの貧弱なデザインを見てきました。
追加された 著者 dsmith,
また、AdvancedTextBoxのようなクラス名が表示されたら、少し心配です。形容詞「Advanced」には正確なセマンティックな意味はないので、私はそれがちょうど機能の袋になると確信しています。私はそのようなクラスから継承することをお勧めしません。
追加された 著者 dsmith,
C - > B - > A という階層に立っていれば、あなたのメソッドの設計が間違っています。 BA.myProcedureC のインスタンスから呼び出すことはできません。
追加された 著者 madth3,

3 答え

これはどう ...

  • AとCを同じパッケージに入れ、Bを別のパッケージに入れます。
  • A.doSomethingA()から「private」を削除する
  • CにAのインスタンスを与える(継承を優先して合成する)
  • CとAは同じパッケージに入っているので、CはいつでもA.doSomethingA()を呼び出すことができます。

ここにAの定義があります

package ac; 

public class A {

    public void myProcedure() {
        doSomethingA();
    }

   void doSomethingA() {}

}

ここにBの定義があります

package b;

public class B extends A {

    @Override
    public void myProcedure() {
        doSomethingB();
       //IT DOESN'T CALL super.myProcedure
    }

    private void doSomethingB() {}

}

Cの定義は次のとおりです

package ac;
// do you really need to extend B? 
public class C {
    A a = new A();

    public void myProcedure() {
        a.doSomethingA(); 
    }

}
2
追加された
CはBを拡張する必要があります。しかし、 protected は問題を解決する可能性がありますか?
追加された 著者 Luke Vo,

一部の外部モジュールがA.myProcedureを呼び出す場合、doSomethingAを公開する必要はありません。他のモジュールはdoSomethingAを直接呼び出すことはありません。 Javaスコープ修飾子の意図的な意図は、他の関数を介して間接的にではなく、直接関数を呼び出すときにのみ適用されることです。このようにして、クラスは、パブリックインターフェイスを定義する少数のパブリック関数を持つことができます。これは慎重に文書化され、非常に安定しています。そうすれば、これらのパブリック関数は任意の数のプライベート関数を呼び出すことができ、パブリックインタフェースを変更することなく、これらのプライベート関数を自由にシャッフルしたり、パフォーマンスを向上させたり、新しい環境などで作業することができます。

0
追加された

doSomethingAは実装の詳細なので、サブクラスが直接呼び出すことができるようにプライベートからプロテクトに変更します。

0
追加された