редагувати: читання файлу трохи довше Мені подобається ідея перезавантаження оператора << >> і додавання його як друга цих класів, проте я не впевнений, як це не порушує інкапсуляцію
Як би це порушило інкапсуляцію?
Ви порушуєте інкапсуляцію, коли дозволяєте необмежений доступ до члена даних. Розглянемо наступні класи:
class c1 {
public:
int x;
};
class c2 {
public:
int foo();
private:
int x;
};
class c3 {
friend int foo();
private:
int x;
};
c1
це , очевидно , НЕ инкапсулируется. Будь-хто може читати та змінювати x
в ній. У нас немає способу застосувати будь-який вид контролю доступу.
c2
очевидно, капсульований. Немає публічного доступу доx
. Все, що ви можете зробити, це викликати foo
функцію, яка виконує якусь змістовну операцію над класом .
c3
? Це менш капсульовано? Чи це дозволяє необмежений доступ до x
? Чи дозволяє доступ до невідомих функцій?
Ні. Це дозволяє точно за допомогою однієї функції отримати доступ до приватних членів класу. Так само, як і c2
зробив. І так само c2
, як одна функція, яка має доступ, - це не "якась випадкова, невідома функція", а "функція, зазначена у визначенні класу". Так якc2
ми можемо побачити, лише переглянувши визначення класів, повний список того, хто має доступ.
То як саме це менш капсульоване? Така сама кількість коду має доступ до приватних членів класу. І кожен, хто має доступ, вказаний у визначенні класу.
friend
не порушує інкапсуляцію. Це змушує деяких програмістів Java відчувати себе некомфортно, тому що, коли вони говорять "OOP", це насправді означає "Java". Коли вони кажуть "інкапсуляція", вони не означають, що "приватні члени повинні бути захищені від довільного доступу", але "клас Java, де єдині функції, які мають змогу отримати доступ до приватних членів, є членами класу", навіть якщо це повна дурниця для кілька причин .
По-перше, як уже показано, це занадто обмежує. Немає причини, чому дружні методи не повинні дозволяти робити те саме.
По- друге, це не є обмежувальним досить . Розглянемо четвертий клас:
class c4 {
public:
int getx();
void setx(int x);
private:
int x;
};
Це, згідно з вищезазначеним менталітетом Java, ідеально інкапсульоване.
І все ж, він дозволяє абсолютно будь-кому читати та змінювати х . Як це навіть має сенс? (натяк: Це не так)
Підсумок: інкапсуляція - це можливість контролювати, які функції можуть отримати доступ до приватних членів. Справа не в тому, де саме знаходяться визначення цих функцій.