클래스와 오브젝트의 차이점과 알아두면 좋을 기본적인 기술에 대하여 서술한다.
클래스와 오브젝트는 형태를 만들어주는 틀과 그 틀로 만들어진 제품이라고 생각해야한다.
즉, 우리가 좋아하는 붕어빵을 만드는 기계를 생각해보면 정형화된 틀이 있다. 이러한 붕어빵 기계를 클래스라고 생각하고, 붕어빵 틀을 통해 만들어진 붕어빵들이 오브젝트라고 생각하면된다.
붕어빵에는 크림붕어빵, 팥붕어빵 등등 같은모양에 다른 내용물이 있는 붕어빵이 있는데 이것을 오브젝트라고 한다.
▼ 클래스 선언(붕어빵 예시)
class 붕어빵기계{
constructor(반죽,내용물){
this.반죽 = 반죽;
this.내용물 = 내용물;
}
cooking(){
console.log(this.내용물+"붕어빵");
}
}
▼ 오브젝트 선언(붕어빵 예시)
const 붕어빵_팥 = new 붕어빵기계("밀가루반죽","팥");
붕어빵_팥.cooking(); // 팥붕어빵
const 붕어빵_크림 = new 붕어빵기계("밀가루반죽","크림");
붕어빵_크림.cooking(); // 크림붕어빵
클래스에서 get,set을 사용하는 이유는 오류 방지를 위해 프로퍼티를 조절하는 역할을 한다고 생각한다.
즉, 커피자판기를 class라고 생각하였을때 커피종류 갯수라는 number타입(int)의 갯수를 프로퍼티로 받고 돈을받는다,커피를만든다,커피를준다 와 같은 메소드가 있다고 가정하였을때, 만약 커피종류에 -1개라는 값을 넣고 오브젝트를 만든다면, 오브젝트는 형성되지만, -1개의 커피갯수를 가진 커피자판기는 객체지향적으로 불가능하다. 이러한 오류값을 제어하기 위하여 get와 set을 사용하여 프로퍼티를 조절하고 오류를 사전에 방지할 수 있다.
▼ set,get없이 선언
class 커피자판기{
constructor(커피종류){
this.커피종류 = 커피종류;//int
}
커피를 만든다(){
console.log("커피만들만들");
}
...
}
const 우리동네1커피머신 = new 커피자판기(-1);// 우리동네1커피머신은 커피갯수가 -1개임??
▼ set,get 선언
class 커피자판기{
constructor(커피종류){
this.커피종류 = 커피종류;//int
}
get 커피종류(){
this.커피종류 = this._커피종류;
}
set 커피종류(value){
if(value<0){
throw Error("커피갯수 음수 안됨");
}else{
this._커피종류 = value;
}
// or
this._커피종류 = value<0 ? 0 : value; //삼항연산자를 이용해서 최소값을 정해놓으면 간편하게 오류 방지 가능.
}
커피를 만든다(){
console.log("커피만들만들");
}
...
}
const 우리동네1커피머신 = new 커피자판기(-1);// 커피갯수 음수 안됨 or 0 으로 만듬.
외부에서 오브젝트 내부의 값을 열람할수 있게 할지 유무를 만들어줌(인캡슐레이션,encapsulation)
class 클래스명{
public = 1;
#private = 1;
}
const 예시 = new 클래스명();
console.log(예시.public); // 1;
console.log(예시.private); // undefined;
메모리 소모를 최적화 하고 클래스별 고유 기능? 을 넣을때 사용함
class 클래스명{
static public = "스태틱변수";
static printPublic{
console.log("스태틱 메소드");
}
}
const 예시 = new 클래스명();
console.log(예시.public); // undefined;
예시.printPublic(); // undefined;
console.log(클래스명.public); // "스태틱변수"
클래스명.printPublic(); // "스태틱 메소드"
공통된 데이터를 가지고 있는 다른 오브젝트를 만들때 공통된 부분을 처리하기 위한 방법?
즉, 사각형과 삼각형 등과 같은 도형을 만들때 사각형과 삼각형은 width와 height라는 공통적인 프로퍼티가 존재한다. 이럴경우 2개의 클래스를 만드는것이 아닌 공통된 값을 처리하는 클래스를 1개 만들고 이것을 상속받아사용한다. 이후 각각의 오브젝트별 수정사항을 중첩(overlay)하여 사용한다.
▼상속을 사용하지 않았을 경우
class rectangle{
constructor(width,height){
this.width = width;
this.height = height;
}
getArea(){
console.log(this.width*this.height);
}
}
class triangle{
constructor(width,height){
this.width = width;
this.height = height;
}
getArea(){
console.log((this.width*this.height)/2);
}
}
const rectangle_obj = new rectangle(200,200);
const triangle_obj = new triangle(200,200);
rectangle_obj.getArea(); //400
triangle_obj.getArea(); //200
▼상속및 다양성 활용
class shape{
constructor(width,height){
this.width = width;
this.height = height;
}
getArea(){
console.log(this.width*this.height);
}
}
class rectangle extends shape{}
class triangle extends shape{
getArea(){ //중첩을 통해 덮어씌우기를 메소드 변경 가능!
super.getArea(); //super를 통해 기본 클래스의 값을 불러오는것도 가능하다.
console.log(this.width*this.height/2);
}
}
const rectangle_obj = new rectangle(200,200);
const triangle_obj = new triangle(200,200);
rectangle_obj.getArea(); //400
triangle_obj.getArea(); // 400(super값) / 200(overlay값)
오브젝트와 클래스 사이의 인스텐스 인지 아닌지를 확인하기 위한 것.
console.log(rectangle_obj instanceof shape); //true;
console.log(rectangle_obj instanceof rectangle); //true;
console.log(rectangle_obj instanceof triangle); //false;
console.log(rectangle_obj instanceof Object); //false;
코드의 재사용성 및 유지보수의 간편함을 위해 객체지향적으로 코드를 설계하는것이 좋아 보임.
즉, 오브젝트를 만들때 재사용가능성이 있는지를 먼저 판단하고, 재사용성이 있다면 클래스로 만들어 보는것도 좋아보임!