반응형
이전 글에서 다시 virtual 키워드를 지우고, main을 아래와 같이 작성해보자.
FOOD type에 MILK로 객체를 생성한 후, SNACK으로 type casting하여 printName을 호출한다.
#include <stdio.h>
#include <iostream>
using namespace std;
class FOOD
{
private:
int price = 0;
public:
void printName() { cout << "FOOD Class" << endl; }
void printPrice() { cout << this->price << endl; }
void printLine() { cout << "=================" << endl; }
};
class SNACK : public FOOD
{
private:
int price = 1000;
public:
void printName() { cout << "SNACK Class" << endl; }
void printPrice() { cout << this->price << endl; }
};
class MILK : public FOOD
{
private:
int price = 500;
public:
void printName() { cout << "MILK Class" << endl; }
void printPrice() { cout << this->price << endl; }
};
int main(void)
{
FOOD* food = new MILK();
SNACK* snack = (SNACK*)food;
snack->printName();
return 0;
}
snack은 type도 SNACK이고 casting도 SNACK으로 cast하였다. 따라서 SNACK에 재정의된 printName이 호출된다.
다시 virtual 키워드를 선언해보자.
class FOOD
{
private:
int price = 0;
public:
virtual void printName() { cout << "FOOD Class" << endl; }
virtual void printPrice() { cout << this->price << endl; }
void printLine() { cout << "=================" << endl; }
};
virtual을 이용해서 형변환된 클래스에서 오버라이딩된 메서드를 사용하도록 하였다.
그러므로 처음에 선언된 MILK 클래스의 printName을 보도록 하였다.
이렇게 virtual로 선언하면 type을 SNACK으로 변경하여도 계속 MILK의 printName을 보게 된다.
virtual이 없는 자바의 경우는 어떻게 될까? (이전 글에서 Main만 수정하였다.)
public class Main {
public static void main(String[] args) {
FOOD food = new MILK();
SNACK snack = (SNACK)food;
snack.printName();
}
}
exception이 발생한다.
virtual이 없는 자바는 타입이 기준이 아닌, 생성된 객체를 기준으로 함수가 호출되었다.
따라서 MILK가 SNACK이 될 수 없다.
반응형
'개발 > C, C++' 카테고리의 다른 글
C++ - 가상 소멸자 (Virtual Destructor) (0) | 2021.08.23 |
---|---|
C++ - explicit 키워드 (0) | 2021.08.22 |
C++ - virtual 키워드 (0) | 2021.08.14 |
C++ - 복사 생성자를 이용한 객체의 깊은 복사 (Deep Copy using Copy Constructor) (0) | 2021.08.10 |
C++ - 명시적 디폴트 생성자 (0) | 2021.07.29 |
댓글