为什么我不能访问受保护的 java 方法,即使我已经扩展了类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1622219/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
why can't i access protected java method even thought i've extended the class?
提问by Matt
Here's the documentation for the protected method:
这是受保护方法的文档:
/** Converts jmusic score data into a MIDI Sequence */
protected javax.sound.midi.Sequence scoreToSeq(Score score)
And I made this little class to extend the class that scoreToSeq method comes from:
我制作了这个小类来扩展 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;
}
}
回答by Jon Skeet
(EDIT: theycallmemorty's answergives the practical advice to avoiding this problem in your case. This answer gives the reasons for why you have to follow that advice, i.e. why the language has been designed that way.)
(编辑:theycallmemorty 的回答给出了在你的情况下避免这个问题的实用建议。这个答案给出了为什么你必须遵循这个建议的原因,即为什么语言是这样设计的。)
You can only access a protected member of another object which is of the same type as the accessing code (or a subclass) - even though the member is declaredin a supertype.
您只能访问与访问代码(或子类)具有相同类型的另一个对象的受保护成员 - 即使该成员是在超类型中声明的。
From the Java Language Specification, section 6.6.2:
Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:
- If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
- If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
设 C 是声明受保护成员 m 的类。仅允许在 C 的子类 S 的主体内访问。此外,如果 Id 表示实例字段或实例方法,则:
- 如果访问是通过限定名称 Q.Id 进行的,其中 Q 是 ExpressionName,则当且仅当表达式 Q 的类型是 S 或 S 的子类时才允许访问。
- 如果访问是通过字段访问表达式 E.Id,其中 E 是主表达式,或通过方法调用表达式 E.Id(. . .),其中 E 是主表达式,那么当且仅当访问被允许如果 E 的类型是 S 或 S 的子类。
This is to allow a type to access members relevant to its own inheritance tree, without defeating encapsulation of other classes. For example, suppose we have:
这是为了允许类型访问与其自身继承树相关的成员,而不会破坏其他类的封装。例如,假设我们有:
A
/ \
B Other
/
C
and A declared a protected member x. Without the rule working the way it does, you could get round encapsulation by putting a member in Other:
并且 A 声明了一个受保护的成员x。如果没有规则按照它的方式工作,您可以通过将成员放入来获得圆形封装Other:
public int getX(A a)
{
return a.x;
}
and just calling that passing in an instance of Bor C- the member would effectively become public, because you could always work around it by introducing another class... not a good idea. With the current rule, you'd have to subclass Bor C- which you may not be able to in the first place.
并且只是在Bor的实例中调用它C- 该成员将有效地变为公共,因为您总是可以通过引入另一个类来解决它......这不是一个好主意。根据当前规则,您必须对Bor进行子类化C- 您一开始可能无法做到这一点。
回答by theycallmemorty
By doing this:
通过做这个:
MidiSynth synth = new MidiSynth();
sequence = synth.scoreToSeq(score);
You are not actually taking advantage of the fact that you've extended the MidiSynth class.
您实际上并没有利用扩展 MidiSynth 类这一事实。
If you were to try
如果你要尝试
this.scoreToSec(score);
Then you'll find you have access to the protected function.
然后您会发现您可以访问受保护的功能。

