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