クラスを拡張したと思っても、なぜ保護されたJavaメソッドにアクセスできないのですか?
-
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の答えは、あなたのケースでこの問題を回避するための実用的なアドバイスを提供します。この答えは、あなたがそのアドバイスに従わなければならない理由、すなわち言語がそのように設計された理由を提供します。)
スーパータイプでメンバーが宣言されている場合でも、アクセスするコード(またはサブクラス)と同じタイプの別のオブジェクトの保護されたメンバーにのみアクセスできます。
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);
保護された機能にアクセスできることがわかります。
所属していません StackOverflow