Интерфейс в ООП
На основе информации по абстрактным классам, наследованию и тому, что указатель на базовый класс является указателем на классы-наследники вырисовывается еще один из способов использования этих понятий – интерфейс, что это такое:
Интерфейс – класс у которого все методы виртуальные, этот класс показывает ВСЕ ДОСТУПНЫЕ методы для работы с подобными классами, т.е. сам интерфейс действий НЕ может выполнять, но его классы-наследники способны реализовать функции интерфейса.
Зачем он нужен? Чтобы создать интерфейс/набор функций для взаимодействия со всеми наследниками и объектами, реализующими этот интерфейс.
Например:
класс-интерфейс огнестрельного оружия IFirearms декларирует методы (виртуальные) shoot(); и reload();
и есть классы-наследники Handgun (пистолет) и AssaultRifle (штурмовая винтовка) в которых эти методы переопределены.
А также есть класс player, который в одном из методов может принимать указатель на базовый класс (IFirearms) и использовать методы, реализованные в классах-наследниках.
В принципе все очень похоже на абстрактный класс, но
в абстрактных классах один или более методов не имеют реализации т.е. мы можем создавать виртуальные и невиртуальные методы + поля класса.
у интерфейса ни один метод не реализован, все они публичные и нет переменных класса.
Реализуем описанный пример:
class IFirearms
{
public:
void virtual shoot();
void virtual reload();
};
class Handgun : public IFirearms //реализуем интерфейс
{
public: //указывать необязательно т.к. public+public
void shoot() override
{
cout<<"shot 6 times "<<endl;
}
void reload() override
{
cout<<"reload 5 sec "<<endl;
}
};
class AssaultRifle : public IFirearms
{
public: //указывать необязательно т.к. public+public
void shoot() override
{
cout<<"refle shot 30 times "<<endl;
}
void reload() override
{
cout<<"reload 10 sec "<<endl;
}
};
class Player
{
public:
void AutoFight(IFirearms &weapon)
{
weapon.shoot();
weapon.reload();
}
};
В main напишем:
Handgun revolver;
AssaultRifle rifle;
Player player;
player.AutoFight(revolver);
cout<<endl;
player.AutoFight(rifle);
Стоит отметить, что интерфейсы в языке C++ обычно обозначаются с заглавной буквы I (например IFirearms), при наследовании класса от интерфейса обычно говорят «реализуем интерфейс» вместо «унаследуемся от класса» поскольку все методы интерфейса виртуальные и для ВСЕХ них нужно писать реализации.