추상 클래스
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 60번째.
abstract class는 순수 가상 function을 하나 이상 포함하는 모든 class입니다. 불완전한 인터페이스를 가지므로 abstract class의 객체를 직접 생성할 수 cannot 있으며, 이는 오직 상속되기 위해 존재합니다.
class Shape {
public:
virtual double area() = 0; // 순수 가상 함수 - Shape를 추상 클래스로 만듦
virtual double perimeter() = 0; // 또 다른 순수 가상 함수
void printInfo() { // 일반 메서드 - 구현이 있음
std::cout << "Area: " << area() << std::endl;
}
virtual ~Shape() = default;
};
Shape s; // 오류: 추상 클래스를 인스턴스화할 수 없음abstract 클래스는 순수 가상 functions(implementation 없음), 일반 가상 functions(기본 implementation 포함), 그리고 비가상 functions를 혼합하여 포함할 수 있습니다. 이를 통해 공통 동작을 define하는 동시에 Derived 클래스가 특정 기능을 구현하도록 요구할 수 있습니다.
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { return 3.14159 * radius * radius; }
double perimeter() override { return 2 * 3.14159 * radius; }
};
Circle c(5.0); // OK: Circle이 모든 순수 가상 함수를 구현합니다
c.printInfo(); // 상속된 printInfo()를 사용하며, Circle의 area()를 호출합니다파생 클래스는 구체 클래스(인스턴스화 가능)가 되려면 순수 가상 함수 all을 구현해야 합니다. 구현되지 않은 함수가 하나라도 남아 있으면 해당 클래스 자체가 abstract로 남습니다. 이 메커니즘은 계층 구조의 모든 구체 클래스가 필요한 기능을 제공하도록 보장합니다.
챌린지
쉬움abstract class가 다양한 미디어 유형에 대한 계약을 정의하는 방식을 보여 주는 미디어 플레이어 시스템을 만들어 보겠습니다. 모든 미디어 플레이어가 수행해야 하는 작업을 정의하는 abstract base class를 만든 다음, 오디오 및 비디오 콘텐츠를 위한 구체적인 플레이어를 구현합니다.
코드를 세 개의 파일로 구성합니다.
MediaPlayer.h: 모든 미디어 유형을 위한 청사진 역할을 하는 abstractMediaPlayerclass를 정의합니다. abstract class에는 다음이 포함되어야 합니다.- protected
std::string title멤버 - protected
int duration멤버(초 단위) - 두 값을 모두 초기화하는 constructor
- pure virtual
play()method: 각 미디어 유형은 서로 다른 방식으로 재생됩니다 std::string을 반환하는 pure virtualgetMediaType()method<title> (<duration>s) - Type: <mediaType>를 출력하는 일반(non-virtual)showInfo()method. 이 method는 유형을 가져오기 위해getMediaType()을 호출해야 합니다- virtual destructor
- protected
Players.h:MediaPlayer에서 상속되는 두 개의 구체적인 미디어 플레이어를 구현합니다.AudioPlayer:- private
std::string artist멤버 - title, duration, artist를 받는 constructor
Playing audio: <title> by <artist>를 출력하도록play()를 Implement"Audio"를 반환하도록getMediaType()을 Implement
VideoPlayer:- private
std::string resolution멤버 - title, duration, resolution을 받는 constructor
Playing video: <title> in <resolution>를 출력하도록play()를 Implement"Video"를 반환하도록getMediaType()을 Implement
- private
main.cpp: 네 개의 입력을 읽습니다(각각 별도의 줄에 입력).- 오디오 트랙 title
- 오디오 duration (정수)
- 비디오 title
- 비디오 duration (정수)
artist가
"Unknown Artist"인AudioPlayer와 resolution이"1080p"인VideoPlayer를 만듭니다. 두 객체를MediaPlayer*포인터 배열에 저장합니다.배열을 순회하면서 각 플레이어에 대해 먼저
showInfo()를 호출한 다음play()를 호출합니다. 각 미디어 항목 사이에 빈 줄을 출력합니다. 작업이 끝나면 dynamically allocated 객체를 정리합니다.
예를 들어 입력이 Summer Vibes, 180, Nature Documentary, 3600인 경우:
Summer Vibes (180s) - Type: Audio
Playing audio: Summer Vibes by Unknown Artist
Nature Documentary (3600s) - Type: Video
Playing video: Nature Documentary in 1080pshowInfo() method가 abstract base class에서 한 번만 정의되지만 pure virtual getMediaType()을 호출한다는 점에 주목하세요. 이는 abstract class가 구체적인 구현과 derived class가 제공해야 하는 method를 함께 사용할 수 있음을 보여 줍니다. 재정의된 모든 method에 override keyword를 사용하는 것을 잊지 마세요.
직접 해보기
#include <iostream>
#include <string>
#include "MediaPlayer.h"
#include "Players.h"
int main() {
// 입력 읽기
std::string audioTitle;
int audioDuration;
std::string videoTitle;
int videoDuration;
std::getline(std::cin, audioTitle);
std::cin >> audioDuration;
std::cin.ignore();
std::getline(std::cin, videoTitle);
std::cin >> videoDuration;
// TODO: 아티스트 "Unknown Artist"로 AudioPlayer 생성
// TODO: 해상도 "1080p"로 VideoPlayer 생성
// TODO: 둘 다 MediaPlayer* 포인터 배열에 저장
// TODO: 배열을 순회하며 각 플레이어에 대해:
// 1. showInfo() 호출
// 2. play() 호출
// 3. 각 미디어 항목 사이에 빈 줄 출력
// TODO: 동적으로 할당된 객체 정리
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러