Javascript

[Javascript] Class와 Object

봄나물소녀 2021. 4. 30. 11:15

1. Class, Object

 

Class

연관있는 Fields(데이터)와 Method(액션)로 이루어진 것. object를 만들기 위한 가상의 틀이다.

 

Object

실제로 존재하고 만들어지는 것. 일상 속에서 비유하자면 자동차, 의자, 커피 등등.

 

쉽게 말해

class는 객체를 만들기 위한 틀이고, object는 그 틀 안에서 실제로 만들어지는  할 수 있겠다. 

드림코딩의 엘리님께서 이를 붕어빵의 틀과 붕어빵으로 비유를 해주셨다! (늘 좋은 강의 감사드려요)

 

찰떡이다.

class person{
    constructor (name,age){ 	
    // field - 생성자(constructor)를 이용하여 object에 필요한 데이터를 전달한다.
        this.name=name; 		
        this.age=age;
    // 전달된 데이터를 바로 할당해준다.
    }
    speak(){				 
    //method
        console.log(`Hi! I'm ${this.name}. ${this.age}years old`);
    }
}

console.log(person); 							
// class가 그대로 뜬다.

const person2 = new person('venny', 20); 			
// 새로운 object를 만들어 준다. 
// 앞에서 constructor에 name과 age가 할당이 되었으므로 새로운 object가 만들어진다.

console.log(person2); 							
// person2 = { name : "venny", age = 20}

console.log(`name : ${person2.name}`); 				
// name : "venny"

console.log(`age : ${person2.age}`);   				
// age : 20

person2.speak(); 								
// Hi I'm venny. 20years old

 

2. Getter 와 Setter

상대방이나 내가 class를 자칫 잘 못 사용해도 제대로 쓸 수 있게 도와줍니다. 자동차로 비유하자면 사이드 브레이크같은 느낌이라고 할까요.

getter와 setter를 이해하기 위해서 자판기를 예를 들어보겠습니다.

 

 

class = coffee vending machine

field = number of coffee

method1 = put coins

method2 = make coffee


 

자, 여기서 coffee의 갯수가 -1개가 되는 것이 가능할까요?

당연히 불가능합니다. 

이때 누군가가 자판기에 들어있는 커피의 갯수를 -1개라고 한다고해도 우리가 0이라고 설정해주는 것.

이것이 getter와 setter를 쓰는 이유입니다.

 

class User{
    constructor(name, age){
        this.name=name;
        this.age=age;
    }


   get age(){  		// get값으로 return을 하고

       return this._age
   }

   set age(value){	 // set 값을 설정해줍니다(값을 설정하기 떄문에 반드시 value를 받아와야합니다.)
    this._age = value < 0 ? 0 : value
   }}

const venny = new User("venny", -1);
const eunmi = new User("gangmi", -5);


console.log(venny.age);
console.log(gangmi.age);

여기서 갑자기 get과 set 안에 등장한 _age 변수는 무엇일까?

 

 

 

constructor(name, age){
        this.name=name;
        this.age=age;
    }

heritance 

constructor를 통해 할당된 this.age를 호출하는 순간 메모리에 있는 데이터를 읽어오는 것이 아니라

getter를 호출한다. 역시 = age 를 호출 시 setter를 호출한다.

 

 

this.age에 전달된 value를 할당할 떄 메모리에 값 업데이트 x. setter를 재호출. 무한 반복.

이를 방지하기 위해 getter와 setter에서 쓰이는 변수를 조금 다르게 해주어야 한다.("_" 추가)

e.g. age ,name, sex -> _age , _name, _sex

 

*알아두면 좋은 지식

Incapsulation.

: number of coffee라는 propertiy를 private으로 만들어주는 것

 

오브젝트나 들어오는 데이터에 상관없이 공통적을 class에서 쓸 수 있는거라면

static고 static method를 이용하는게

메모리 관리에 효과적.

 

3. Inheritance

 

▒ 다른 class를 확장시키기 위한 class 방식.

shape에 공통적으로 쓰이는 속성값을 한 번 정의한 뒤 재사용할 수 있어 더 간편하다.

유지보수에 좋다. 손가락이 덜 아프다.

 

도형을 만든다고 생각해보자.

모든 도형에 공통적으로 들어가는 요소는 넓이를 구할 수 있는 width, height가 있고

그 외에는 color 등이 있겠다

이 3가지를 field에 넣고 똑같이 class를 만든다.

만드려는 도형의 이름을 class 이름로 설정하고 우리가 만든 Shape class를 그대로 가져오는

"extends Shape{ }" 를 추가해준다.

 

class Shape{
    constructor(width, height, color){ // 3가지 field.
        this.width=width;
        this.height=height;
        this.color=color;
    }

    draw(){ 
	console.log(`drawing ${this.color} color of`)
    }
    
    getArea(){
    return this.width * this.height;
    }
}

class Rectangle extends Shape{}; // extends 키워드만 이용하게 되면 shape에 있는 모든 것들이 포함된다.
class Triangle extends Shape{};


const rectangle = new Rectangle(20, 20, 'yellow');
rectangle.draw();
console.log(rectangle.getArea())

const triangle = new Triangle(30,30, 'green'); 
triangle.draw();
console.log(triangle.getArea());

오직 extends 키워드 하나로 shape에 있는 모든 것을 재사용 할 수 있다니 :0

 

그런데!

rectangle과는 다르게 triangle 은 (width*height) / 2를 해야 넓이가 나온다.

여기서 extends의 다형성이 빛을 발한다.

class Rectangle extends Shape{};
class Triangle extends Shape{    // 다형성이 빛을 발하는 부분.
    draw(){
        super.draw(); 
        
        console.log('🔺');
        // 위에서 언급한 draw를 재정의 하고 싶다면 super.draw (super : 부모의 method도 불러와라)
    }
    
    getArea(){
        return (this.width * this.height) / 2; // 삼각형에 맞는 공식으로 재정의
        }

    }
}; 


const rectangle = new Rectangle(20, 20, 'yellow');
rectangle.draw();
console.log(rectangle.getArea())

const triangle = new Triangle(30,30, 'green'); 
triangle.draw(); // (30*30) / 2 = 450
console.log(triangle.getArea());

 

 

 

흠..아무래도 영상을 더 보고 좀더 이해한 뒤

힌반 더 깔끔하게 정리해야겠다.