C++

C++) 인터페이스(Interface)

zzugest1 2024. 12. 26. 21:18

인터페이스 : 객체 지향 프로그래밍의 개념으로, 클래스가 특정 메서드를 구현하도록 강제하는 일종의 계약을 정의한다.

 

class Human
{
public:
    void Print() { std::cout << "사람." << std::endl; }

    void InterFunction1() {} // 텅텅 빈 함수

    virtual void InterFunction2() {}
    
    virtual void Interface() = 0;
    
 }

 

위와 같이 Human이라는 부모 클래스를 만들었다고 가정했을 때, Print() 함수는 "사람"을 출력하지만 아래의 InterFunction1, InterFunction2, Interface는 아무것도 없이 비어 있다. InterFunction1,2는 비어있는 함수라 자식 클래스들이 상속을 받아 따로 작성을 해 사용을 해야 한다.

 

InterFunction2앞에 붙어 있는 virtual은 가상함수라는 뜻이다. 실제로 하는 기능은 전혀 없지만 이 단어가 붙어있는 함수를 보고 다음 개발자가 코드와 함수 구성에 대한 지침을 얻을 수 있다. (이 경우에는 virtual이 앞에 없어도 됨.)

 

Interface 함수에는 = 0이 붙어있는데 이렇게 작성함으로서 InterFunction1 ,2와 달리 가상함수를 자식 클래스에게 완전히 강제시킬 수 있다. (이 경우에는 virtual이 앞에 필수) 이렇게 내용이 완전히 빈 가상함수를 순수 가상함수라고 한다.  그리고 Human만으로는 함수들을 단독으로 실행할 수 없게 된다. 이걸 이용하기 위해선 자식클래스들을 생성 후 Interface함수를 다시 만들어 함수 안의 내용을 채워줘야 한다.

 

class Child : public Human // MyClass의 자식
{
public:
    void Print() {     
        std::cout << "자식." << std::endl;
    }

    virtual void InterFunction2() override
    {
        std::cout << "이전된 함수" << std::endl;
    }

    virtual void Interface() override
    {
        std::cout << "인터페이스에 의한 함수" << std::endl;
    }
};

 

위와 같이 Human을 상속받는 자식 클래스 Child를 만들었을 때, Print()함수는 부모 클래스에도 작성되어 있으므로 문제 없이 자식 클래에서 생성하고 사용가능하다. 

 

InterFunction2와 Interface 함수를 새로 작성을 하였을 때 부모 클래스와 마찬가지로 virtual을 작성해주었다. 이쪽도 가상함수의 관계라는 뜻이다. 그리고 함수 뒤에 override가 붙어 있는데 이는 이 함수가 지침을 받아서 실제 내용을 작성한 상속받은 쪽이라는 표시이다. 이 두 표시는 사실 없어도 되지만 있는 편이 지침 유지에 훨씬 도움이 된다고 한다.

 

Child* child = new Child();

child->Print();  
child->InterFunction2()
child->Interface()

 

위에서 만든 Child클래스를 객체로 사용할 때 위의 코드들을 main에서 실행시키면 Child에서 작성한 함수안의 내용들이 출력되는 것을 알 수 있다.

 

class Doctor : public Human
{
public:
    virtual void Interface() override
    {
        std::cout << "나는 박사입니다." << std::endl;
    }

    void Go()   
    {
        std::cout << "가고 싶은 대로 갑니다." << std::endl;
    }

};

 

Human을 상속하는 Doctor라는 자식 클래스를 위와 같이 생성했을 때, Interface 함수는 부모 클래스와 마찬가지로 작성했지만 Go 라는 함수는 부모 클래스에 없다. 이 두 함수를 출력을 하기 위해

Human* doctor = new Doctor();

 

생성은 Doctor로 실제 사용은 Human으로 하기 위해 작성했을 때, 

doctor->Interface();
doctor->Go();

 

위 두 함수를 실행했을 때, Interface는 정상작동되지만 Go는 작동되지 않는다. 이는 자료형이 Human*이여서 작동이 안되는 것이다.  Doctor * doctor = new Doctor(); 으로 객체를 생성하면 작동하지만 위와같이 자료형이 Human인 경우엔

 

((Doctor*)doctor)->Go();

 

위와 같이 인터페이스가 적용된 부모 클래스로 지정한 자식 객체에서 고유한 데이터를 쓴다면 자기 클래스로 다시 형변환을 하는 방법도 있다. 이렇게 부모(상위) 클래스로 사용하던 객체를 본래의 자식(하위) 클래스로 바꾸어서 사용하는 것을 다운 캐스팅이라고 한다.

반대로 최초에 부모 클래스로서 자식 클래스를 만드는 것. 혹은 자식 클래스르 만들고 이를 부모에 할당하는 것을 업 캐스팅이라고 한다. (Human* doctor  = new Doctor ())

 

 

'C++' 카테고리의 다른 글

C++) 클래스(Class)  (0) 2025.01.08
C++) 동적 할당  (0) 2025.01.06
C++) 포인터(Pointer)  (0) 2025.01.06
C++) 템플릿(Template)  (0) 2024.12.26
C++) STL과 자료구조  (0) 2024.12.23