Это невозможно из-за полиморфизма. Рассмотрим следующее. У вас есть метод в классе A
с некоторым модификатором доступа, который не является private
. Почему бы и нет? Потому что, если он был приватным, тогда ни один другой класс не мог даже знать о его существовании. Так что это должно быть что-то еще, и что-то еще должно быть доступно от где-то.
Теперь давайте предположим, что вы передаете экземпляр класса C
на номер где-то. Но вы его базовому типу A
заранее, и поэтому вы в конечном итоге этот код где:
void somewhereMethod(A instance) {
instance.method(); // Ouch! Calling a private method on class C.
}
Один хороший пример того, как это разбилось в Qt QSaveFile. В отличие от Java, C++ фактически позволяет снизить права доступа. Поэтому они сделали именно это, запретив метод close()
. В итоге у них есть подкласс QIODevice
, который на самом деле не является QIODevice
. Если вы передадите указатель на QSaveFile
некоему методу, принимающему QIODevice*
, они все равно могут позвонить close()
, потому что он открыт в QIODevice
. Они «исправили» это, сделав QSaveFile::close()
(который является приватным) на вызов abort()
, поэтому, если вы сделаете что-то подобное, ваша программа немедленно сработает. Не очень приятное «решение», но лучшего нет. И это всего лишь пример плохого дизайна OO. Вот почему Java этого не позволяет.
Редактировать
Не то, что я пропустил, что ваш класс является абстрактным, но я пропустил тот факт, что B extends C
, не A
. Таким образом, то, что вы хотите сделать, совершенно невозможно. Если метод public
в B, он будет общедоступным и во всех подклассах. Единственное, что вы можете сделать, это документ, что его нельзя называть , а, возможно, переопределить его, чтобы выбросить UnsupportedOperationException
. Но это привело бы к тем же проблемам, что и к QSaveFile
.Помните, что пользователи вашего класса могут даже не знать, что это экземпляр C
, поэтому у них даже не будет возможности прочитать его документацию.
В целом это очень плохая идея OO-wise. Возможно, вам стоит задать еще один вопрос о конкретной проблеме, которую вы пытаетесь решить с помощью этой иерархии, и, возможно, вы получите достойные советы о том, как это сделать правильно.
Вы можете сделать переопределенный окончательный, но не закрытый. Кроме того, вы можете сделать это устаревшим и отказаться от неподдерживаемого исключения операции (guava делает это для неизменных коллекций) –