클래스와 인스턴스

태로샐러드·2021년 9월 11일
0
post-thumbnail

지난번 포스팅에서 객체 지향에 대해서 정리했다.
오늘 포스팅할 클래스와 인스턴스는 자바스크립트에서 객체 지향으로 프로그래밍하는 패턴이다.

class와 instance란 ?

  • class : 모델이 되는 큰 청사진(blueprint)
  • instance : 청사진을 바탕으로 한 객체를 만드는 것

그래서 어떻게 만드는가.

🍫 javascript 에서 클래스 만들기

// ES5
function Car(brand, name, color) {
  this.brand = brand;
  this.name = name;
  this.color = color;
}

Car.prototype.dirve = function() {
  console.log (this.name + '가 운전을 합니다');
}
// ES6
class Car {
  constructor (brand, name, color) {
    this.brand = brand;
    this.name = name;
    this.color = color;
  }
  
  drive() {
    console.log (this.name + '가 운전을 합니다');
  }
}

위는 ES5의 문법이고 아래는 ES6의 문법인데 ES6의 문법이 더 직관적이다.
여기 보이는 이 자체가 생성자(constructor) 함수다.
뜬금없이 이 자체가 생성자 함수라니 이해가 잘 안갈수도 있지만 아래에 추가적으로 정리하고자 한다.
그냥 지금은 아 이렇게 클래스를 정의할 수 있고 이걸 생성자 함수라고 하는구나 정도만 알면 된다.
일반 함수와 구분하기 위해 이름의 첫문자를 대문자로 설정한다.
이렇게 클래스(청사진)를 정의했다면 이 클래스를 인스턴스로 만들어 사용해야하는데 아래처럼 사용한다.

let avante = new Car('현대', '아반떼', '블랙');
let sonata = new Car('현대', '소나타', '화이트');

new라는 키워드를 앞에 붙이고 정의한 해당 클래스명을 뒤에 붙이면 인스턴스 객체가 생성된다.
생성된 인스턴스 객체는 class의 고유한 속성과 메소드를 가지게된다.
여기서 뒤의 파라미터들은 class를 정의할 때 설정했던 파라미터로 그대로 넘어간다.

class Car {
  constructor (brand, name, color) {
    this.brand = brand;
    this.name = name;
    this.color = color;
  }
  
  drive() {
    console.log (this.name + '가 운전을 합니다');
  }
}

인스턴스가 생성되면 파라미터 값들이 전달되고 이때 this는, 생성된 인스턴스의 실행 context가 되어,
아래와 같이 부여된다.

let avante = new Car('현대', '아반떼', '블랙');
// this.brand = '현대'
// this.name = '아반떼'
// this.color = '블랙'

위에서 this로 정의하는 것들은 속성(상태)이고, 생성자 함수 외에 다른 함수가 있는 것을 볼수 있는데 이것이 메소드(기능)다.

class Car {
  constructor (brand, name, color) {
    this.brand = brand;
    this.name = name;
    this.color = color;
  }
  
  //메소드(기능)
  drive() {
    console.log (this.name + '가 운전을 합니다');
  }
}

🍫 class문법으로 상속시키기

객체지향 프로그래밍의 주요 특징 중 하나로 상속(Inheritance)를 이야기했었다.
class문법으로 어떻게 상속시키는지 알아보자.

class Person {
  constructor(name, age, gender, interests) {
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.interests = interests;
  }
  
    greeting() {
    console.log(`Hi! I'm ${this.name}`);
  };
}

이런 Person 객체가 하나 있고, Student라는 자식 객체를 하나 만든다고 치자.
방법은 의외로 간단하다. extends 키워드를 사용하면 된다.

class Student extends Person  {
  constructor(name, age, gender, interests, subject, grade) {
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.interests = interests;
    
    this.subject = subject;
    this.grade = grade;
  }
}

위와 같이 class 명을 정의하고 그 뒤에 상속받을 부모 클래스명을 extends 키워드와 같이 적어주면 된다.
그리고 자식 class에만 있는 특별한 속성을 constructor(생성자)의 인자로 추가한 후 아래에 속성을 정의해주면 된다.
부모클래스의 메소드는 자식클래스 내에 추가로 작성하지 않아도 사용 가능하다.

그런데 저렇게 constructor(생성자)의 인자들이 쭉 한 줄로 나열되어 있으면 아무래도
자식 클래스에서 새로 추가되는 속성이 무엇인지, 부모 클래스에서 물려받은 속성이 무엇인지
단번에 파악하기 힘들 것이다.
이때 super() 연산자를 사용하면 조금 가독성 좋은 코드를 만들 수 있다.

class Student extends Person  {
  constructor(name, age, gender, interests, subject, grade) {
    super(name, age, gender, interests);
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.interests = interests;
    
    this.subject = subject;
    this.grade = grade;
  }
}

위와 같이 constructor 생성자 내에 super()를 정의하고,
부모클래스에서 물려받은 속성들을 인자로 적어주면 끝이다.

만약, 부모 클래스의 메소드를 조금 변형해서 사용하고 싶다면?

위에서 자식 클래스에서는 부모 클래스를 따로 작성하지 않아도 사용할 수 있다고 했었다.
그런데 이 메소드를 살짝 변형해서 쓰고 싶을 수도 있을 것이다.
이럴 때도 super연산자를 활용하면 된다.

class Student extends Person  {
  constructor(name, age, gender, interests, subject, grade) {
    super(name, age, gender, interests);
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.interests = interests;
    
    this.subject = subject;
    this.grade = grade;
  }
  
  greeting() { return super.greeting() + 추가.변경할 내용 }
}

자식에서도 greeting을 한 번 더 정의해주고,
return값을 저렇게 super.greeting()으로 하면 부모의 메소드를 그대로 불러오는데
여기에 변경할 내용을 추가하거나 수정하면 된다.
다른 속성과 달리 dot notation으로 표현한 이유는 greeting()은 속성이 아니고 메소드기 때문이다.

profile
기획, 개발공부, 그 외 잡다한 여정 기록 (SEMI로)

0개의 댓글

관련 채용 정보