본문 바로가기
Dev. Handbook/Javascript

[Javascript] ES5+ 기초강의 6 - class vs object, 객체지향언어

by breezyday 2022. 7. 1.

1. Class, Object, JavaScript class

Class 란
- 실 세계의 물건들을 속성과 행동으로 정의한 것
- filed와 method를 묶어주는 컨테이너

- field      : 속성
- method : 행동

- template
- 한 번만 선언
- 실제 데이터는 없음 : no data in
Object (instance)
- class가 실체화한 것 : instance of a class
- 여러 개를 만들 수 있음
- 실제 데이터를 가지고 있음 : data in
class  : template (템플릿)
object : instance of a class (템플릿의 실체화)

 

JavaScript Class

  • ES6에서 추가됨
  • 클래스가 도입되기 전에는 object를 바로 생성할 수 있었음
  • syntactical sugar(편리함) over prototype-based inheritance
  • 기존의 prototype 기반을 상속해서 기능을 제공하므로 prototype을 알아둘 필요가 있다.

2. Class declaration : 클래스 선언

// 1. Class declarations
class Person {
    // constructor
    constructor(name, age) {
        // fileds
        this.name = name;
        this.age = age;
    }

    // methods
    speak() {
        console.log(`${this.name}: hello!`);
    }
}

// object 생성 : Class의 instance를 생성
const ellie = new Person('ellie', 20);

// object 사용
console.log(ellie.name);
console.log(ellie.age);
ellie.speak();

 

3. Getter and Setter

클래스에서 field에 대한 접근을 private으로 설정하여

field에 무분별한 접근을 막아줄 수 있으며, 이를 encapsulation이라고 한다.

 

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

    // getter
    // 함수가 재귀적으로 호출되는 것을 막기 위해 변수명 앞에 '_'를 추가
    get age() {
        return this._age;
    }

    // setter
    // - 잘못된 입력 값 처리를 추가할 수 있음
    // - 함수가 재귀적으로 호출되는 것을 막기 위해 변수명 앞에 '_'를 추가
    set age(value) {
        // if (value < 0) {
        //     throw Error('age can not be negative');
        // }
        this._age = value<0 ? 0 : value;
    }
}

 

Getter
- 함수가 재귀적으로 호출되는 것을 막기 위해 변수명 앞에 '_'를 추가
Setter
- 함수가 재귀적으로 호출되는 것을 막기 위해 변수명 앞에 '_'를 추가
- 잘못된 입력 값 처리를 추가할 수 있음

 

const user1 = new User('Steve', 'Bob', -10); // 잘못 입력 된 age 값
console.log(user1.age);                      // Setter의 코딩 덕분에 '0'으로 설정

 

4. Fields (public, private) 

최근에 추가된 기능으로 지원하는 브라우저가 적음.

지금은 사용하기 일러서 Babel을 사용하여 컴파일하는 것이 좋음.

 

class Experiment {
    publicFields = 2;   // public
    #privateField = 0;  // private 
}

const expreiment = new Experiment();
console.log(expreiment.publicFields); // 정상적으로 출력
console.log(expreiment.privateField); // undefined : 값을 조회하지 못함

   

5. Static properties and methods : static 속성 & 메서드

최근에 추가된 기능으로 지원하는 브라우저가 적음.

지금은 사용하기 일러서 Babel을 사용하여 컴파일하는 것이 좋음.

 

class Article {
    // 클래스 한정 변수로 instance 전에 접근 가능.
    static publisher = 'Dream Coding';

    constructor(articleNumber) {
        this.articleNumber = articleNumber;
    }

    // static 메소드 : static 변수 조회 가능
    static printPublisher() {
        console.log(Article.publisher);
    }

    printArticleNumber() {
        console.log(this.articleNumber);
    }

    printPublisherNotStatic() {
        console.log(Article.publisher);
    }
}

const article1 = new Article(1);
const article2 = new Article(2);

console.log(article1.publisher);    // undefined : static값은 static에서만 참조 가능
article1.printArticleNumber();      // 일반 method

 

static 값은 static 메서드에서만 참조 가능

 

// static 함수 조회
// - 객체가 아니라 클래스를 직접 조회
// - static 메소드를 사용
console.log(Article.publisher);     // Article 클래스 조회

Article.printPublisher();           // staitc 메소드 사용

article1.printPublisherNotStatic();  // not defined

 

6. Inheritance : 상속

하나의 클래스를 확장하여 다른 클래스를 만들 수 있음.

부모 클래스를 상속받아 자식 클래스를 만든다고 함.

 

extends 키워드 사용.

 

부모 클래스

class Shape {
    constructor(width, height, color) {
        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 { } 
class Triangle extends Shape { 
    // override : 기존 메소드를 재 작성
    draw() {
        super.draw();     // 부모 메소드를 호출
        console.log('▲')  // 새로운 기능을 추가
    }

    // override getArea()
    getArea() {
        return (this.width * this.height) / 2;
    }

    // override ToString()
    // 모든 객체의 부모는 Object
    // Object로 부터 상속받은 메소드 가운데 하나
    toString() {
        return `Triangle- color:${this.color}`;
    }
}

 

자식 클래스는 부모 메서드를 상속받아 그대로 사용하거나,

부모 클래스의 메서드를 호출하거나,

부모 메서드의 이름만 사용하여 새로운 메서드를 작성(재정의 : override)할 수 있음.

 

// 기본 class를 상속한 클래스의 객체
const rectangle = new Rectangle(20, 20, 'blue');
rectangle.draw();                   // 상속받은 함수 호출
console.log(rectangle.getArea());   // 상속받은 함수 호출
console.log(rectangle.toString());  // '[object Object]'

// 기본 class를 상속하고 메소드를 재정의(override)한 클래스의 객체
const triangle = new Triangle(20, 20, 'red');
triangle.draw();                    // 재정의(override)한 함수 호출
console.log(triangle.getArea());    // 재정의(override)한 함수 호출
console.log(triangle.toString());   // 'Triangle- color:red'

 

7. Class checking [ instance of ]

instance of
- 어떤 클래스의 객체인지 식별할 수 있는 방법을 제공
- 어떤 클래스의 객체인 경우 true를 반환
- 상속을 받은 클래스는 부모 클래스로도 식별 가능
- Object는 모든 클래스의 부모 클래스이므로 모든 클래스는 true를 반환.

 

console.log(rectangle instanceof Rectangle);    // true
console.log(triangle instanceof Rectangle);     // false
console.log(triangle instanceof Triangle);      // true
console.log(triangle instanceof Shape);         // true : 부모 클래스를 상속받은 클래스
console.log(triangle instanceof Object);        // true : Object는 모든 클래스의 부모 클래스

 

 

 

 

 

댓글