Я 'відкрив' інтерфейси, і я почав їх любити. Краса інтерфейсу полягає в тому, що це договір, і будь-який об'єкт, який виконує цей договір, може використовуватися там, де потрібен цей інтерфейс.
Проблема інтерфейсу полягає в тому, що він не може мати реалізацію за замовчуванням, що є болем за життєві властивості та перемагає DRY. Це також добре, тому що він утримує реалізацію і систему нерозв'язується. Спадщина, з іншого боку, підтримує більш жорстке з'єднання і має можливість порушити інкапсуляцію.
Випадок 1 (Спадкування з приватними членами, хороша інкапсуляція, щільно з'єднана)
class Employee
{
int money_earned;
string name;
public:
void do_work(){money_earned++;};
string get_name(return name;);
};
class Nurse : public Employee:
{
public:
void do_work(/*do work. Oops, can't update money_earned. Unaware I have to call superclass' do_work()*/);
};
void HireNurse(Nurse *n)
{
nurse->do_work();
)
Випадок 2 (лише інтерфейс)
class IEmployee
{
virtual void do_work()=0;
virtual string get_name()=0;
};
//class Nurse implements IEmployee.
//But now, for each employee, must repeat the get_name() implementation,
//and add a name member string, which breaks DRY.
Випадок 3: (кращий з обох світів?)
Схожий на випадок 1 . Однак уявіть, що (гіпотетично) C ++ не дозволяв переосмислювати методи, за винятком тих методів, які є чисто віртуальними .
Так, у випадку 1 переосмислення do_work () призведе до помилки під час компіляції. Щоб виправити це, ми встановлюємо do_work () як чистий віртуальний і додаємо окремий метод increment_money_earned (). Як приклад:
class Employee
{
int money_earned;
string name;
public:
virtual void do_work()=0;
void increment_money_earned(money_earned++;);
string get_name(return name;);
};
class Nurse : public Employee:
{
public:
void do_work(/*do work*/ increment_money_earned(); ); .
};
Але навіть у цьому є проблеми. Що робити, якщо через 3 місяці Джо Кодер створить «Докторського працівника», але він забуває викликати increment_money_earned () у do_work ()?
Питання:
Чи справді випадок 3 вищий за справу 1 ? Це тому, що це "краща інкапсуляція" або "більш вільно пов'язана", чи якась інша причина?
Чи справді випадок 3 кращий за випадок 2, оскільки він відповідає сухій?