Почему Java не поддерживает частное / защищенное наследование, такое как C ++? [закрыто]


12

Унаследовав класс в C ++, пользователь может указать спецификатор доступа, например,

class Base
{
    public int mem1;
    protected in mem2;
};

class Derived1 : **private** Base
{
    // mem1 will be private here.
    // mem2 will be private here.
};

class Derived2 : **protected** Base
{
    // mem1 will be protected here.
    // mem2 will be protected here.
};

class Derived2 : **public** Base
{
    // mem1 will be public here.
    // mem2 will be protected here.
};

Но то же самое невозможно в Java, т. Е. Extends в java всегда похож на «публичное» наследование в C ++.

Может ли кто-нибудь объяснить причину этого?


16
Никому не нужна причина, чтобы опустить функцию, нужна причина (в идеале, несколько хороших), чтобы добавить ее.

1
На это можно ответить только умозрительно, проголосовав за закрытие.
Джимми Хоффа

Ответы:


10

Большинство преимуществ, которые дает вам частное / защищенное наследование, может быть легко достигнуто с помощью инкапсуляции. Томас Эдинг привел несколько хороших примеров случаев, которые можно упростить с добавлением частного / защищенного наследования, и, хотя это допустимые случаи, существуют обходные пути, которые не требуют частного / защищенного наследования и являются более «идиоматическими» (в Java наименее).

Разработчики языка Java, очевидно, считали, что затраты на сложность, необходимые для поддержки частного / защищенного наследования (включая множественное наследование), перевешивают выгоду, которую он обеспечит.


1
Стоит отметить, что в C ++ есть некоторые важные различия между частным наследованием и включением в качестве члена, но они вращаются вокруг порядка инициализации и множественного наследования и, таким образом, не переводятся в более простую объектную систему Java.
Ян Худек

2
-1: « Любая выгода, которую дает вам частное / защищенное наследование, может быть легко достигнута путем инкапсуляции». Неправильно. Я бы согласился с « Большинство преимуществ ...»
Томас Эдинг

@ThomasEding Можете ли вы привести пример чего-то, что может быть достигнуто с помощью частного / защищенного наследования, но не с помощью инкапсуляции (или, по крайней мере, чего-то, что потребовало бы много работы для инкапсуляции)? Я, честно говоря, не могу думать об этом, но я открыт для убеждения.
PSWG

2
Ой, прости насчет этого. Вот несколько примеров на C ++. (1) Предположим, что вы хотите внутренне рассматривать класс Bкак A( Bприватно наследуемый A), чтобы вы могли полиморфно использовать его в каком-либо методе. С композицией это может быть сделано, но это намного грязнее. Здесь вам необходимо создать отдельный подкласс A'(возможно, внутренний класс), который реализует используемые вами функции. Вам также необходимо вручную делегировать изменения родительскому Bклассу ( Bсоздает A'друга, A'принимает ссылку на него B). Я полагаю, это не так сложно сделать, но в коде есть проблемы. (Продолжение)
Томас Эдинг

2
... (2) Если вы хотите Bполучить доступ к защищенным переменным в A, частное наследование снова проще реализовать поверх композиции. С помощью композиции вы можете реализовать A'аналогично описанному выше и / или повысить доступ к защищенным переменным. (3) Предположим, вам нужна единая статическая переменная-член, которая является одной и той же точной переменной в экземплярах шаблона. Решение заключается в частном наследовании от не шаблонного базового класса, который имеет статический член. Композиция не может решить эту проблему, хотя другие методы могут (например, подружить некоторый другой класс с участником).
Томас Эдинг

9

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.