Чому 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, тобто розширення в java завжди схоже на "публічне" успадкування в C ++.

Може хтось пояснить причину цього?


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

1
На це можна відповісти лише спекулятивно, голосуючи закрити.
Джиммі Хоффа

Відповіді:


10

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

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


1
Варто зазначити, що в C ++ є деякі важливі відмінності між приватним успадкуванням і включенням як члена, але вони обертаються навколо порядку ініціалізації та багаторазового успадкування і, таким чином, не перетворюються на більш просту об’єктну систему Java.
Ян Худек

2
-1: " Будь-яка вигода, яку надає вам приватна / захищена спадщина, легко досягти шляхом інкапсуляції." Неправильно. Я згоден з « Більшість переваг ...»
Thomas Eding

@ThomasEding Чи можете ви навести приклад того, що можна досягти завдяки приватному / захищеному спадкуванню, але не шляхом інкапсуляції (або, принаймні, чогось, що потребує великої роботи для інкапсуляції)? Я, чесно кажучи, не можу придумати одного, але я готовий переконатися.
pswg

2
Ну, вибачте про це. Ось кілька прикладів в C ++. (1) Припустимо, ви хочете внутрішньо розглядати клас Bяк A( Bприватно успадкований від A), щоб ви могли поліморфно використовувати його в якомусь методі. З композицією це можна зробити, але це набагато м’ясніше. Тут вам потрібно створити окремий підклас A'(можливо, внутрішній клас), який реалізує функціонал, який ви використовуєте. Вам також потрібно буде вручну делегувати зміни до батьківського Bкласу ( Bробить A'друга, A'приймає посилання на B). Я думаю, це зробити не надто важко, але в коді виникає безлад. (Продовження)
Томас Едінг

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

9

Оскільки Java не має багаторазового успадкування, і все має бути (публічно) успадковано Object, на Яві немає місця, де приватне чи захищене спадкування дало б дійсну програму.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.