Re: Нащо потрібен protected?
Ну так протектед не тільки змінні, а і функції бувають.
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → C++ → Статті → Нащо потрібен protected?
Для відправлення відповіді ви повинні увійти або зареєструватися
Ну так протектед не тільки змінні, а і функції бувають.
Хоча я не знайомий із C++ і її специфікою, але думаю стаття написана ширше, ніж лише для C++.
Мене більше цікавить навіщо використовувати private, коли є protected. З точки зору тестування, private не піддається перевіркам у зовнішньому класі. protected може приховати непотрібні змінні ззовні, і піддається тестуванню.
Мабуть у private-член треба ховати щось, що взагалі не треба тестувати, чи що? Тобто код з private повинен бути елементарним, так? Єдине для чого я можу уявити потребу використовувати саме private, а не protected, так це унікальні якісь ідентифікатори, властиві лише даному конкретному екземпляру. - Все!
Де я помиляюсь?
Хоча я не знайомий із C++ і її специфікою, але думаю стаття написана ширше, ніж лише для C++.
Мене більше цікавить навіщо використовувати private, коли є protected. З точки зору тестування, private не піддається перевіркам у зовнішньому класі. protected може приховати непотрібні змінні ззовні, і піддається тестуванню.
Мабуть у private-член треба ховати щось, що взагалі не треба тестувати, чи що? Тобто код з private повинен бути елементарним, так? Єдине для чого я можу уявити потребу використовувати саме private, а не protected, так це унікальні якісь ідентифікатори, властиві лише даному конкретному екземпляру. - Все!
Де я помиляюсь?
А як же можливість змінити внутрішню реалізацію, не зачіпаючи інтерфейс?
Якщо ви хочете змінити private-метод, ви берете його і змінюєте.
Якщо ви хочете змінити protected-метод, вам треба донести це до ваших користувачів, щоб вони змінили спосіб, у який вони використовують ваш клас.
Змінювати внутрішню реалізацію не чіпаючи інтерфейс - то є добре, але це стосується усіх без виключень модифікаторів доступу: public, protected, private.
Зрозуміло як саме треба сповіщати про свої зміни у випадку приватних і не приватних членів - не питання. Питання: "Як працювати з приватними модифікаторами доступів, в умовах, коли ми пишемо щось складніше за Hello world, тобто в умовах, коли ми повинні писати тести?".
Можете навести приклад, коли є потреба змінювати щось "приватно" і не можна обійтись одним лише protected?
Змінювати внутрішню реалізацію не чіпаючи інтерфейс - то є добре, але це стосується усіх без виключень модифікаторів доступу: public, protected, private.
Ні, все, що оголошено з модифікаторами protected і public, відноситься до інтерфейсу.
Як працювати з приватними модифікаторами доступів, в умовах, коли ми пишемо щось складніше за Hello world, тобто в умовах, коли ми повинні писати тести?
Чому не можна по адекватності роботи public-методів зробити висновок про адекватність роботи private-методів?
Ні, все, що оголошено з модифікаторами protected і public, відноситься до інтерфейсу.
Якщо ви про той інтерфейс, що оголошується через ключове слово interface, то він взагалі-то буває виключно публічним, ніякого protected чи private. Але якщо під інтерфейсом розуміти взагалі "сигнатуру методу", в такому разі можна говорити й про protected, коли до нього повинен мати доступ нащадок, також можна говорити й про private, коли в класі є певний метод і він має свій інтерфейс, тобто свою сигнатуру для зовнішнього доступу в межах поточного класа.
Чому не можна по адекватності роботи public-методів зробити висновок про адекватність роботи private-методів?
Трохи дивне питання. Іншими словами ви стверджуєте: "Якщо система працює несправно, то обов'язково не справно працюють лише публічні методи." - Так?
Якщо ви про той інтерфейс, що оголошується через ключове слово interface, то він взагалі-то буває виключно публічним, ніякого protected чи private. Але якщо під інтерфейсом розуміти взагалі "сигнатуру методу", в такому разі можна говорити й про protected, коли до нього повинен мати доступ нащадок, також можна говорити й про private, коли в класі є певний метод і він має свій інтерфейс, тобто свою сигнатуру для зовнішнього доступу в межах поточного класа.
Інтерфейс - це способи взаємодії класу і зовнішнього світу. Через протектед можна взаємодіяти зі світом, через приват - ні.
Трохи дивне питання. Іншими словами ви стверджуєте: "Якщо система працює несправно, то обов'язково не справно працюють лише публічні методи." - Так?
Отак ближче.
quez, не знаю які справи у цьому плані у тієї мови, яку ви знаєте, але якщо говорити, наприклад, за TypeScript, то ми легко можемо оголосити інтерфейс навіть в одному якомусь методі просто для того, щоб далі в коді узгоджено працювати з певним типом даних або із сигнатурою функції. Тобто у TypeScript зовсім не обов'язково використовувати інтерфейси для узгодження між класом і зовнішнім світом.
Судячи із того, що ООП у TypeScript спроектовано подібно до того, як це зроблено у C#, а C# створювалась, на скільки я знаю, як спрощений/удосконалений варіант C++, то припускаю, що описане мною використання інтерфейсів властиво і для C++.
ktretyak, за допомогою ключового слова private повідомляється, що всі члени даних або функції-члени, які підуть далі, будуть закритими (поки не буде поставлений інший модифікатор доступу). Таким чином, до цих членів можна буде звернутися тільки з коду, що відноситься до класу, в якому знаходяться ці члени. Отже, будучи в зовнішньому контексті, не можна буде безпосередньо звернутися до закритого члена даних.
Це забезпечує цілісність об'єкта. Наприклад, у вас може бути об'єкт "автомобіль", що має член даних "паливо". Встановлюючи модифікатор private, ви гарантуєте, що він (член даних "паливо") не прийме неприпустимого значення (наприклад, не стане негативним числом), оскільки до нього немає безпосереднього доступу. Це інкапсуляція. А інкапсуляція не дозволяє зовнішньому коду безпосередньо звертатися до внутрішньої структури об'єкта. Навпаки, завдяки інкапсуляції такий код використовує для доступу до об'єкта певний інтерфейс.
Щоб звертатися до закритих членів, необхідно писати функцію-члени для такої можливості. В такому випадку не потрібно звертатися до конкретного члена даних. Можливо, у вас вже виникло питання: навіщо ж робити члени даних закритими, якщо до будь-якого члену даних все одно можна звернутися через функцію доступу? Справа в тому, що необмежений доступ до членів даних зазвичай не допускається.
На прикладі про автомобіль-паливо:
void Car::SetFuel(int fuel)
{
if (fuel < 0)
{
cout « "Помилка. Значення палива не може бути негативним"; // запобігаємо встановленню від'ємного значення
}
else
{
m_Fuel = fuel; // m_Fuel є закритим членом даних класу Car
}
}
Ось чому краще private, а не protected. Бо private може замінити protected за допомогою використання функцій доступу, а protected - ні.
Тобто у TypeScript зовсім не обов'язково використовувати інтерфейси для узгодження між класом і зовнішнім світом.
Ви говорите зовсім не про те. Інтерфейси як мовні конструкції нас зараз не цікавлять. В своєм ширшому значенні інтерфейс — це спосіб взаємодії зі світом як класу, так і програми, і комп’ютера, і будь-якої чорної скриньки з кнопками і ручками, в яку ми не можемо (чи не хочемо) заглядати.
Протектед-метод — це одна із таких кнопок. Коли ви оголосили метод як протектед, це означає, що десь в світі хтось може унаслідуватись від вашого класу і викликати ваш метод у своєму коді і ви вже не можете змінити йому ні ім’я, ні те, що він повертає.
Приватні методи зовсім інакші. Це нутрощі чорної скриньки. Їх ви можете викидати і повертати хоч у кожному релізі, не турбуючись про користувачів вашої програми — здатність до роботи їх програм від цього не постраждає.
...Ось чому краще private, а не protected. Бо private може замінити protected за допомогою використання функцій доступу, а protected - ні.
Чесно кажучи, я не зрозумів про що ви говорите. Тобто я добре розумію як працюють public, protected, private члени класу, і які переваги дає приховування змінних класу від безпосереднього звернення до них ззовні, але я не зрозумів перевагу private над protected в даному поясненні.
Підсумовуючи дискусію в цій темі, здається я побачив більше сенсу саме у змінних (що є членами класу) з модифікатором доступу private. Тобто для мене тепер залишається відкритим питання нащо використовувати приватні методи, враховуючи що вони не піддаються тестуванню.
Приватні методи зовсім інакші. Це нутрощі чорної скриньки. Їх ви можете викидати і повертати хоч у кожному релізі, не турбуючись про користувачів вашої програми — здатність до роботи їх програм від цього не постраждає.
Приватні члени класу ніколи не "висять у повітрі" (в противному разі це був би мертвий код), до них обов'язково звертаються або з public, або з protected метода. А це значить, що "викидання їх з програми" може потягнути за собою непрацездатність коду точно так само, якби ми "викидали" public чи protected методи.
quez написав:Приватні методи зовсім інакші. Це нутрощі чорної скриньки. Їх ви можете викидати і повертати хоч у кожному релізі, не турбуючись про користувачів вашої програми — здатність до роботи їх програм від цього не постраждає.
Приватні члени класу ніколи не "висять у повітрі" (в противному разі це був би мертвий код), до них обов'язково звертаються або з public, або з protected метода. А це значить, що "викидання їх з програми" може потягнути за собою непрацездатність коду точно так само, якби ми "викидали" public чи protected методи.
Ви ж все зрозуміли. Викидаєте повільні методи, прикручуєте швидкі, і т. п. Коли завгодно і як завгодно.
Для відправлення відповіді ви повинні увійти або зареєструватися