クラスを拡張したと思っても、なぜ保護されたJavaメソッドにアクセスできないのですか?

StackOverflow https://stackoverflow.com/questions/1622219

  •  06-07-2019
  •  | 
  •  

質問

プロテクトメソッドのドキュメントは次のとおりです。

/** Converts jmusic score data into a MIDI Sequence */
protected  javax.sound.midi.Sequence scoreToSeq(Score score)

そして、この小さなクラスを作成して、scoreToSeqメソッドが由来するクラスを拡張しました。

public class MidiSequence extends MidiSynth{

    public Sequence getSequence(Score score){
        MidiSynth synth = new MidiSynth();
        Sequence sequence = null;
        try
        {
                    // Here I get the error saying that the method has
                    // protected access in MidiSynth
            sequence = synth.scoreToSeq(score);

        }
        catch (InvalidMidiDataException e)
        {
            /*
             *  In case of an exception, we dump the exception
             *  including the stack trace to the console.
             *  Then, we exit the program.
             */
            e.printStackTrace();
            System.exit(1);
        }

        return sequence;

    }
}
役に立ちましたか?

解決

(編集: theycallmemortyの答えは、あなたのケースでこの問題を回避するための実用的なアドバイスを提供します。この答えは、あなたがそのアドバイスに従わなければならない理由、すなわち言語がそのように設計された理由を提供します。)

スーパータイプでメンバーが宣言されている場合でも、アクセスするコード(またはサブクラス)と同じタイプの別のオブジェクトの保護されたメンバーにのみアクセスできます。

Java言語仕様のセクションから6.6.2

  

Cを、   保護されたメンバーmが宣言されています。アクセス   の本文内でのみ許可されます   CのサブクラスS。さらに、Id   インスタンスフィールドまたはインスタンスを示します   メソッド、次に:

     
      
  • アクセスが修飾名Q.Idによる場合(QはExpressionName)、   次の場合、アクセスが許可されます。   式Qのタイプの場合のみ   SまたはSのサブクラスです。
  •   
  • アクセスがフィールドアクセス式E.Idによる場合(Eはプライマリ)   式、またはメソッド呼び出しによる   式E.Id(。。。)、ここでEは   一次式、その後のアクセスは   Eのタイプの場合にのみ許可   SまたはSのサブクラスです。
  •   

これは、他のクラスのカプセル化を無効にすることなく、型が自身の継承ツリーに関連するメンバーにアクセスできるようにするためです。たとえば、次のようなものがあるとします:

     A
    / \
   B   Other
  /
 C

and Aは、保護されたメンバー x を宣言しました。ルールが正常に機能しない場合、メンバーを Other

に入れることでラウンドカプセル化を取得できます。
public int getX(A a)
{
    return a.x;
}

そして、そのパスを B または C のインスタンスに渡すだけで-他のクラスを導入することでいつでも回避できるため、メンバーは事実上公開されます。良いアイデアではありません。現在のルールでは、 B または C をサブクラス化する必要があります-そもそもできません。

他のヒント

これにより:

MidiSynth synth = new MidiSynth();
sequence = synth.scoreToSeq(score); 

実際には、MidiSynthクラスを拡張したという事実を利用していません。

試してみる場合

this.scoreToSec(score);

保護された機能にアクセスできることがわかります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top