들어가기 앞서 우선 절차지향,
#include <iostream>
using namespace std;
int main()
{
string car1Name;
string car1maker;
int car1maxSpeed;
car1maxSpeed = 220;
showSpeed(car1maxSpeed);
std::cout << car1maxSpeed << std::endl;
}
void showSpeed(int _spd)
{
std::cout << _spd << std::endl;
}
▲객체 지향이 적용되지 않은 일반적 절차지향 코딩
두번째 자동차, 세번째 자동차를 만들 상황에 놓이면 코드량이 비약적으로 늘어나는 문제점이 있음
1. 특징만 뽑아서 추상화
#include <iostream>
using namespace std;
//추상화로 특징 추출해냄.
class Car
{
public:
string Name;
string maker;
int maxSpeed;
void showSpeed() { std::cout << maxSpeed << std::endl; }
private:
};
int main()
{
Car car1;
car1.maxSpeed = 220;
car1.showSpeed();
car1.maker = "Honda";
}
▲ 특징만 뽑아내어 자동차라는 클래스를 만듦.
실제 존재하는, 혹은 만들고자 하는 대상으로부터 특성, 특징, 주요 행동들만 추출하여 하나에 모으는 것을 추상화라고 함
아직 문제가 있는데, 해당 클래스로 찍어낼 경우 맴버 변수가 노출되어 있어서 코딩 실수, 안전과는 거리가 멀게 됨
2. 정보 은닉 및 캡슐화
#include <iostream>
using namespace std;
//추상화로 특징 추출해냄.
class Car
{
private:
string Name;
string maker;
int maxSpeed;
public:
void SetMaxSpeed(int _spd) { maxSpeed = _spd; }
int GetMaxSpeed() { return maxSpeed; }
};
int main()
{
Car car1;
car1.SetMaxSpeed(220);
cout << car1.GetMaxSpeed() << endl;
}
▲ 맴버변수를 프라이빗으로 바꾸어 직접적인 맴버변수 노출을 막고
게터 세터와 같은 함수를 통해야만 접근 할 수 있게 바뀜
데이터 구조와 방법을 하나로 묶는것. 함수를 통하여 변수를 건드려야 하는데, 이렇게 외부로부터 정보 보호 해주는건 정보 은닉이라고 함.
3. 상속성
#include <iostream>
#include <vector>
using namespace std;
//추상화로 특징 추출해냄.
class Car
{
private:
string Name;
string maker;
int maxSpeed;
public:
void SetMaxSpeed(int _spd) { maxSpeed = _spd; }
int GetMaxSpeed() { return maxSpeed; }
void doWork() { cout << "단순 주행" << endl; }
};
class Tractor
{
private:
string Name;
string maker;
int maxSpeed;
public:
void SetMaxSpeed(int _spd) { maxSpeed = _spd; }
int GetMaxSpeed() { return maxSpeed; }
void doWork() { cout << "추수" << endl; }
};
class Excavator
{
private:
string Name;
string maker;
int maxSpeed;
public:
void SetMaxSpeed(int _spd) { maxSpeed = _spd; }
int GetMaxSpeed() { return maxSpeed; }
void doWork() { cout << "땅파기" << endl; }
};
int main()
{
Car car1;
car1.SetMaxSpeed(220);
cout << car1.GetMaxSpeed() << endl;
}
▲트랙터나 포크레인같은 자동차와 비슷한 클래스를 만들었다면
특징은 비슷한데, 중복된 사항이 많은 클래스들이 많이 생김
#include <iostream>
#include <vector>
using namespace std;
//추상화로 특징 추출해냄.
class Car
{
protected:
string Name;
string maker;
int maxSpeed;
public:
void SetMaxSpeed(int _spd) { maxSpeed = _spd; }
int GetMaxSpeed() { return maxSpeed; }
void doWork() { cout << "단순 주행" << endl; }
};
class Tractor : public Car
{
public:
void doWork() { cout << "추수" << endl; }
};
class Excavator : public Car
{
public:
void doWork() { cout << "땅파기" << endl; }
};
int main()
{
Car car1;
Tractor tractor;
Excavator excavator;
car1.doWork();
tractor.doWork();
excavator.doWork();
}
▲상속을 통하여 중복 코드를 줄인 모습
자식 클래스가 부모 클래스의 특징을 물려받는것. 중복 코드도 줄일 수 있고, 확장에 유용
차나, 트렉터등 종류 및 관리해야 할 객체가 늘어나면 다시 코드가 길어지는 문제 발생
int main()
{
Car *car1 = new Car();
Car *car2 = new Car();
Car *car3 = new Car();
Tractor *tractor = new Tractor();
Tractor *tractor2 = new Tractor();
Excavator *excavator = new Excavator();
Excavator *excavator2 = new Excavator();
vector<Car*> carContainter;
carContainter.push_back(car1);
carContainter.push_back(car2);
carContainter.push_back(car3);
for (auto eachCar : carContainter)
{
eachCar->doWork();
}
vector<Tractor*> tractorContainter;
tractorContainter.push_back(tractor);
tractorContainter.push_back(tractor2);
for (auto eachTractor : tractorContainter)
{
eachTractor->doWork();
}
vector<Excavator*> exContainter;
exContainter.push_back(excavator);
exContainter.push_back(excavator2);
for (auto eachEx : exContainter)
{
eachEx->doWork();
}
}
▲상속받은 제각각의 개체들에게 부여된 기능을 써본 결과, 불필요한 과정반복이 보이기 시작
이럴 때, 다형성을 활용
4. 다형성
int main()
{
Car *car1 = new Car();
Car *car2 = new Car();
Car *car3 = new Car();
Tractor *tractor = new Tractor();
Tractor *tractor2 = new Tractor();
Excavator *excavator = new Excavator();
Excavator *excavator2 = new Excavator();
vector<Car*> vehicleContainter;
vehicleContainter.push_back(car1);
vehicleContainter.push_back(car2);
vehicleContainter.push_back(car3);
vehicleContainter.push_back(tractor);
vehicleContainter.push_back(tractor2);
vehicleContainter.push_back(excavator);
vehicleContainter.push_back(excavator2);
for (auto eachVehicle : vehicleContainter)
{
eachVehicle->doWork();
}
}
▲하위 자식객체가 상위 Car형으로 바뀌어 컨테이너에 담긴 모습
필요에 따라, 객체가 자유롭게 형을 바꾸어 활용될 수 있는것을 다형성이라고 부름.
형을 바꾸었긴 하나, 해당 코드를 실행해보면 아직 문제가 있음
Car형으로 바꾸어서 같은 컨테이너에 담긴건 좋았으나, Car에 있는 함수가 호출되어 버리는 문제 발생
class Car
{
protected:
string Name;
string maker;
int maxSpeed;
public:
void SetMaxSpeed(int _spd) { maxSpeed = _spd; }
int GetMaxSpeed() { return maxSpeed; }
virtual void doWork() { cout << "단순 주행" << endl; }
};
class Tractor : public Car
{
public:
virtual void doWork() override{ cout << "추수" << endl; }
};
class Excavator : public Car
{
public:
virtual void doWork() override { cout << "땅파기" << endl; }
};
▲가상함수인 Virtual 및, 오버라이딩을 통해, 자식객체였을 경우
이것을 실행하여라 하는 재정의 코드 작성
▲형을 바꾸어 관리하여도 본 객체의 행동을 취하는 모습.
객체가 다양한 형태를 띌 수 있는 것을 말함. 예를들어 부모 포인터로 자식 객체를 만들수도 있고, 필요시 자식 객체가 부모객체로 모습을 바꾸어 활용될 수도 있음.
'정보들 > 토막지식 관련' 카테고리의 다른 글
깊은 복사 vs 얕은 복사. 그리고 복사 생성자 (0) | 2021.03.16 |
---|---|
WinAPI 아이콘 바꾸는 방법 (0) | 2020.06.23 |
상대 카메라 설명 영상 (0) | 2020.06.23 |
운영체제 - Round Robin (0) | 2020.06.23 |
바이트 패딩 (0) | 2020.06.23 |