Class와 Instance

이효범·2022년 4월 24일
0

ES6 - OOP & FRP

목록 보기
11/15
post-thumbnail

Class와 Instance 에 대해서 알아보도록 한다.

Class와 Instance

기본적으로 Javascript의 Class는 es6 버전부터 정리가 되기 시작했다.
그리고 Javascript에서 Class 개념을 확장시켜서 만들어진 것이 Typescript 이다. 즉 JS + Class => Typescript 이다.

기본적으로 Typescript 는 OOP 개념이다. 이와 다르게 Javascript는 기본적으로 Functional 프로그래밍이다. 따라서 Class 개념 자체가 원래는 없었다.
즉, 없었는데 추가시킨 것이다. 왜냐니깐 현재 프로그래밍의 가장 기본적인 추세가 OOP이기 때문에 추가시킨 것이라 볼 수 있다.

Class 의 정교한 개념과 설명은 추후 Typescript 를 정리할 때 하도록 하고, 여기서는 개발적인 측면에서만 한번 살펴보도록 한다. Typescript에서는 Class가 아주 정교하게 구성이 된다. 만드는 방법이라던가 운영하는 방법이라던가 하는 방식이 정교한데, Javascript 에서는 그렇게 정교하지는 않다.

어쨋거나, OOP 에서 굉장히 중요한 핵심인 점이 Class 와 Instance 개념이니, 이에 대해서 자세히 이해를 해두어야 한다.

필자의 개인 블로그에도 Class 에 대한 상세한 설명을 적어논 글들이 있으니 참고하면 좋을 듯 하다.


Class 자체는 붕어빵 틀이라고 이해하면 편하고 Instance는 이 틀에 맞춰 만들어진 붕어빵이라고 이해하면 편하다.

따라서 인스턴스는 굉장히 다양하고 여러개가 있고 클래스는 하나만 있게 되겠다.

다음은 Car 라고 하는 인스턴스를 만들어내는 클래스이다. 그리고 클래스 내부에 인스턴스를 만들어 내는 함수를 constructor 라고 부른다.

class Car {
  constructor(arg) {
   this.carProperty1 = arg; 
  }
};

const aCarInstance = new Car('This is a car instance');
console.log(aCarInstance) // Car {carProperty1: This is a car instance'}

또한 인스턴스 자체는 하나의 Object이다.

위와 같은 형태가 가장 기본적인 형태이고, 또한 클래스 내부에 함수를 정의할 수 있다.

class Car {
  constructor(arg) {
   this.carProperty1 = arg; 
  }
  
  // method => 주어 동사를 구성한다.
  // instance method => 주어가 인스턴스
  // class method => 주어가 클래스 그 자체
  drive() {
   console.log('I am a car method.') 
  }
};

const aCarInstance = new Car('This is a car instance');
console.log(aCarInstance) // Car {carProperty1: This is a car instance'}

클래스 내에 정의된 함수들을 method라고 얘기를 하는데, 이 메소드는 여러 개가 있을 수 있다.
method와 function의 차이점이 있는데 이 메소드는 function 중에서 클래스 인스턴스와 주어 동사 관계를 구성하게 된다.
이게 무슨 말이냐하니깐 다음과 같이 console.log(aCarInstance.drive()) 를 출력해보도록 하자.

그러면 "I am a car method" 라고 출력되게 되는데 이는 곧
aCarInstance 가 주어가 되고 drive 가 동사가 된다는 의미이다.

이렇게 주어 역할을 하는 인스턴스와 이에 대응하는 동사 역할을 하는 메소드를 인스턴스 메소드라고 한다.

추후에 클래스 메소드라는 것도 공부하게 될텐데 이는 주어가 클래스 그 자체이다.

한 가지 더 기억해야할 것은 이 클래스를 만드는 가장 주요한 목적과 용도 중에 하나가 바로 클래스는 자손을 가질 수 있다는 것이다. 그래서 기존의 Class 를 불려받은 또 다른 Class를 만들 수 있다.

class Car {
  constructor(arg) {
   this.carProperty1 = arg; 
  }
  
  // method => 주어 동사를 구성한다.
  // instance method => 주어가 인스턴스
  // class method => 주어가 클래스 그 자체
  drive() {
   console.log('I am a car method.') 
  }
};

const aCarInstance = new Car('This is a car instance');
console.log(aCarInstance) // Car {carProperty1: This is a car instance'}

class Sedan extends Car {
  
}
class SUV extends Car {
  
}
class Truck extends Car {
  
}

위의 Sedan 이라고 하는 클래스는 Car 클래스의 자식이 되는 클래스이다.
그렇다면 이 Sedan 이라고 하는 클래스가 만들어 내는 인스턴스는 기본적으로 기존의 Car 클래스가 만들어내는 인스턴스의 모든 특징과 모든 기능을 다 가진다. 그리고 자기만의 고유한 기능과 데이터를 가질 수 있다.

위의 코드처럼 Sedan 이외에도 다양한 구성을 만들어 낼 수 있는 것이 바로 클래스의 상속 개념이다.


// ... 생략
console.log(aCarInstance); // Car {carProperty1: This is a car instance'}

class Sedan extends Car {
  constructor(anArg) {
    super(anArg.carArg);
    this.sedanProperty1 = anArg.type;
  }
};

const anArg = { carArg: 'This is car instance', type: 'Sedan' };

const aSedan1 = new Sedan(anArg);

console.log(aSedan1); // Sedan {carProperty1: 'This is car instance', sedanProperty1: "Sedan"}

기억해야할 점은 Car 클래스를 상속받는 Sedan 클래스가 부모 클래스의 인스턴스의 특징을 다 가지기 위해서는 위킈 코드와 같이 super를 호출해야 한다는 것이다.

super를 호출한다는 것은 Car 인스턴스를 새로 하나 만든다는 의미이다. Car 인스턴스를 만들고 난 후에 자기만의 또다른 데이터를 만들어나가는 것이 가장 일반적인 형태이다.

즉, 후손 클래스 인스턴스는 부모 클래스가 가지는 모든 것을 다 가지고 자기 것을 추가해서 가지는 것이 기본적인 상속 개념이다.


위의 설명이 그렇게 정교한 메커니즘을 가지고 있지는 않지만 개괄적으로 어떤 클래스를 구성하고 인스턴스를 만들고 그 인스턴스들간의 부모 자식 관계가 구성이 될 수 있도록 기본적인 개념을 이용할 수 있게끔,
자바스크립트가 ES6 이후로 클래스 개념을 추가한 것이라고 볼 수 있다.

그런데 이러한 정교한 개념을 적용시켜놓은 것이 Typescript 이니,
추후에 Typescript를 정리하는 시간을 통해 OOP에 대한 개념을 완전히 이해해보도록 하자.


Class와 Instance 연습 문제

다음 연습 문제들을 구현해보면 Class와 Instance에 대해 좀 더 자세히 이해해보도록 하자.

문제

// Initialize the Life's 'power' to 100.
// The constructor will be called with an 'living' object thath has a 'name' property.
// Assign value the 'name' property of the Life

// The Human inherits the Life, and should have a 'talk' method.
// The only argument to this talk method is another instance of the Human class.
// The instance of Human that is passed in should have their 'power' increased by 10

class Life {
 constructor() {
   
 }
}

class Human {
  
}

소스 코드


const living = { lifeName: 'Nature', humanName: 'Superman', power: 100 };

class Life {
 constructor(living) {
   this.name = living.lifeName;
   this.power = living.power;
 }
}

const aLifeInstance = new Life(living);
console.log(aLifeInstance); // Life {name: "Nature", power: 100}

class Human extends Life {
  constructor(living) {
    super(living);
    this.name = living.humanName;
  }
  talk(human) {
    return human.power += 10;
  }
}

const aHumanInstance1 = new Human(living);
const aHumanInstance2 = new Human(living);
console.log(aHumanInstance1); // Human {name: 'Superman', power: 100}

aHumanInstance1.talk(aHumanInstance2);
console.log(aHumanInstance2.power); // 110
profile
I'm on Wave, I'm on the Vibe.

0개의 댓글