почему я не могу получить доступ к защищенному методу Java, даже думал, что я расширил класс?

Мне нравится делать это следующим образом:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // Hide the table view header by default.
    NSIndexPath *index = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView scrollToRowAtIndexPath:index atScrollPosition:UITableViewScrollPositionTop animated:NO];
}

Таким образом, вам не нужно беспокоиться о том, насколько высокий ваш заголовок. Это просто работает!

8
задан Jon Skeet 25 October 2009 в 22:03
поделиться

2 ответа

(РЕДАКТИРОВАТЬ: ответ ониcallmemorty дает практический совет, как избежать этой проблемы в вашем случае. Этот ответ дает причины, по которым вы должны следовать этому совету, то есть почему язык был разработан таким образом.)

Вы можете получить доступ только к защищенному члену другого объекта, который имеет тот же тип, что и код доступа (или подкласс) - даже если член объявлен в супертип.

Из Спецификации языка Java, раздел 6.6.2 :

Пусть C будет классом, в котором объявляется защищенный член m. Доступ разрешено только в теле подкласс S класса C. Кроме того, если Id обозначает поле экземпляра или экземпляр метод, то:

  • Если доступ осуществляется по квалифицированному имени Q.Id, где Q - это ExpressionName, то доступ разрешен, если и только если тип выражения Q является S или подклассом S.
  • Если доступ осуществляется посредством выражения доступа к полю E.Id, где E является первичным выражение или вызов метода выражение E.Id (...), где E - Первичное выражение, тогда доступ разрешено тогда и только тогда, когда тип E является S или подклассом S.

Это позволяет типу получать доступ к членам, относящимся к его собственному дереву наследования, без нарушения инкапсуляции других классов. Например, предположим, что у нас есть:

     A
    / \
   B   Other
  /
 C

и A объявлен защищенным членом x . Если правило не работает так, как оно работает, вы могли бы обойти инкапсуляцию, поместив член в Other :

public int getX(A a)
{
    return a.x;
}

и просто вызвав его в экземпляре B или C - член фактически станет общедоступным, потому что вы всегда можете обойти его, введя другой класс ... не лучшая идея. В соответствии с текущим правилом вам придется создать подкласс B или C , что, возможно, у вас не получится изначально.

17
ответ дан 5 December 2019 в 05:45
поделиться

Делая это:

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

Вы фактически не пользуетесь тем фактом, что вы расширили класс MidiSynth.

Если бы вы попробовали

this.scoreToSec(score);

, тогда вы обнаружите, что у вас есть доступ к защищенной функции.

12
ответ дан 5 December 2019 в 05:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: