Следует ли интерфейсу состоять только из чистых виртуальных методов?

87
09 июня 2021, 21:40

Является ли хорошей практикой добавлять в интерфейс методы с имплементацией, которая основана поверх других методов этого интерфейса? Например:

#include <string>
#include "iostream"
struct IEmployee
{
  virtual ~IEmployee() = default;
  virtual std::string const& GetFirstName() const = 0;
  virtual std::string const& GetLastName() const = 0;
  virtual std::string GetFullName() const
  {
    return GetFirstName() + " " + GetLastName();
  }
};
class Employee : public IEmployee
{
public:
  Employee(std::string const& firstName, std::string const& lastName):
    firstName_(firstName), lastName_(lastName)
  {}
  ~Employee() override = default;
  std::string const& GetFirstName() const { return firstName_; }
  std::string const& GetLastName() const { return lastName_; }

private:
  std::string firstName_;
  std::string lastName_;
};
int main()
{
  IEmployee* employee = new Employee("John", "Smith");
  std::cout << employee->GetFullName() << std::endl;
  delete employee;
  return 0;
}

Или же интерфейс должен состоять только из чистых виртуальных функций?

Как мне видится, интерфейс должен состоять только из чистых виртуальных функций. А если в него добавляется имплементация, то тогда это уже абстрактный класс. Следовало бы в вышеприведенном примере унаследовать от интерфейса IEmpoyee абстрактный класс AbstractEmployee, в нем поместить имплементацию GetFullName и уже от AbstractEmployee унаследовать Employee?

Answer 1

Что такое интерфейс?... Это множество методов, определяющая отношение между объектами. Все классы имеют интерфейс, просто абстрактный класс не делает ничего более, чем обеспечивать своим интерфейсом производным классам. Так что интерфейс может состоять из любых функций (или даже не только функций...). Чистые виртуальные функции обязывают определять их в неабстрактных производных классах. А если в него добавляется имплементация, то производный класс может не переопределять(оставлять реализацию такой же)_ вот и вся разница. Если разновидность(дочерной класс) абстрактного класса тоже является абстрактным( узловой класс), значит есть везкие причины считать, что этот дочерной класс создан только для обеспечения интерфейсом своих производных и не может иметь собственных экземпляров. Например, если есть иерархия Форма -> Закрытая_форма -> ..., то как создать обьект Закрытая_форма?.. поэтому класс Закрытая_форма служит как узловой для производных от Форма. В вашем случаи не вижу смысла создать дополнительный класс... Скажу больше: не вижу смысла в базовом классе IEmployee, если вы сразу можете написать класс Employee с таким же интерфейсом.

Answer 2

Интерфейсным классом называется абстрактный класс, не имеющий данных и состоящий в основном из чисто виртуальных функций. Такой класс может иметь обычные виртуальные функции (не чисто виртуальные), например деструктор. Также могут быть статические функции-члены, например функции-фабрики.

READ ALSO
Как разбить строку на слова C++ (Arduino)

Как разбить строку на слова C++ (Arduino)

На вход мы должны дать "test=qwerty" разделить нужно по = Например split("test=qwerty","=") на выходе должны получить массив ["test","qwerty"]

99
В чём отличие функции от метода в C++?

В чём отличие функции от метода в C++?

На пути обучения C++ столкнулся с такими понятиями, как методы и функции и, собственно, не нахожу отличий между нимиОписываются они одинаково...

112
Как правильно создать локальный хук используя c++ dll?

Как правильно создать локальный хук используя c++ dll?

Здравствуйте уважаемые господа программистыСразу скажу - я новичок в C++ и многого не знаю, по этому не кидайте тапками

106
С++. Проблема со всем. Visual Studio Code

С++. Проблема со всем. Visual Studio Code

Только начал программировать на C++, в итоге ничего не понять, как начатьПопытался установить на Visual Studio Code и C++, и code runner, в итоге написал простенькую...

189