Javascript 객체지향? 클래스 ?

박요셉·2023년 10월 27일
0

Javascript

목록 보기
6/11

우테코 1주차 야구게임과 관련하여 자바스크립트의 클래스를 이해하고 사용하기 위해 공부 중 정리한 것들을 모아서 올림.

제이슨님 readme 기능목록

  • 1부터 9까지의 서로 다른 임의의 수 3개를 생성한다. - NumberGenerator#createRandomNumbers()
  • 컴퓨터의 수(3자리)와 플레이어의 수(3자리)를 비교할 수 있다. - Referee#compare()
    • 몇 개의 숫자가 같은지를 알 수 있다. - Judgement#correctCount()
    • 특정 자리에 특정 숫자가 있는지 알 수 있다. - Judgement#hasPlace()
  • 같은 수가 다른 자리에 있으면 볼이다.
  • 같은 수가 같은 자리에 있으면 스트라이크이다.
  • 같은 수가 전혀 없으면 낫싱이다.

영상 정리

코딩을 시작함에 있어 어떤 것을 만들지 적고 시작하자. (package baseball;)
클래스, 함수의 이름을 정했다면 그 이름 답게 작동해야한다.
add(number1, number2) <- 메소드의 시그니쳐, 아이덴티파이라고

클래스를 사용하여 인스턴스를 만들었을 때 각각의 인스턴스는 서로 영향을 주지 않는다.
teacher , cal 인스턴스에서 클래스에서 선언된 변수를 바꾼다해도 teacher의 값과 cal의 값은 다르다.

객체지향 ?
1. 기능을 가지고 있는 클래스를 인스턴스화(=객체)한다.
2. 필요한 기능을 (역할에 맞는) 각 인스턴스가 수행하게 한다.(의인화)
3. 각 결과를 종합한다.

기능 목록을 작성 후 어떤 이름을 쓸까? 어떤 이름의 클래스 하에 있을까? 생각 -> 정리가됨
그런 후에 기본적인 뼈대를 작성해보자!

클래스에서 다른 클래스의 기능을 가져온다는 것을 객체지향에서는 협력한다고 한다.

가브리엘님 클래스와 객체 발표 정리

출처([10분 테코톡] 가브리엘의 클래스와 객체)

클래스 생성

class Car {
  constructor(name) { //생성자
    this.name = name;
    this.position = 0;
  }
  
  move() { //메소드
    this.position += 1;
  }
  
  honk() { //메소드
    console.log(`${this.name} : ${'빵'.repeat(this.position)}`;
  }
}

const car = new Car('가브리엘');
// 클래스 앞에 new를 붙여주면 인스턴스화가 가능하다.

클래스 내부에는 생성자 메서드, 프로토타입 메서드, 정적 메서드 3가지가 올 수 있다.

생성자 메서드

contructor라는 특수 키워드로 지정이 되있어서 1개 이하만 올 수 있고 이름 변경이 불가능하다.
추가로 암묵적으로 this를 반환하고 있기 때문에 return이 불가능하다.

프로토타입 메서드

move() 메서드는 사실 FunctionCar.prototype.move = function () {}처리된다.
특별한 명시가 없으면 프로토타입에 저장된다.

정적 메서드

class Car {
  constructor(name, date) {
    this.name = name;
    this. date = date;
  }
  
  static createCar() {
    //this는 Car입니다.
    return new this('가브리엘',new Date());
  }
  static staticMethod() {
  	console.log(this === Car);
  }
}

car.staticMethod(); // true

const car = Car.createCar();

console.log(car); // Car {name: '가브리엘', date : 2023-02-21T18:03:43}

메서드 앞에 static을 입력하면 정적 메서드가 된다.
정적 메서드는 프로토타입이 아닌 클래스 함수 자체에 설정 되며, 인스턴스를 생성하지 않아도 호출할 수 있게된다.

어떤식으로 사용 되는가?

클래스에서 인스턴스를 생성하지 않고 클래스 내부의 메서드에서 this를 반환하는 식에서 new를 안쪽에서 붙혀주는 방식으로 스스로를 생성하게 해서 팩토리 메서드로 활용하는 방식이다.

getter/setter

접근자 프로퍼티로 get과 set 키워드를 제공한다.

class Car {
  constructor(name, date) {
    this.name = name;
    this. date = date;
  }
  
  get name() {
    return this._name
  }
  
  set name(newName) {
  	this._name = newName;
  }
}

const car = new Car('가브리엘');
console.log(car); // Car {_name: '가브리엘', position : 0}
console.log(car.name); //가브리엘
car.name = '엘리브가';
console.log(car.name); //엘리브가

position과 달리, name 변수는 _name으로 관ㄹ리된다. 왜일까?

객체를 생성하고나서 인터셉터가 있으면 그냥 name이 아니라 underscore를 붙히는게 한 때 권장이 됬다.

constructor의 영향도 있다.
생성자를 생성하면서 바로 변수로 저장되는 것이 아니라 생성자 함수도 setter로 접근하려는 시도 때문에 이름을 겹치게 할 수가 없었다.

underscore가 없다면? 오류가난다.
왜냐? setter 내부의 this.name도 자기 자신을 호출하려고 시도하기 때문에
생성자 내부의 this.name도 setter를 건들고 setter내부의 this.name도 자기 자신을 건드는 거기 때문에 callstack 오류가 난다.

private을 활용한 getter/setter

게터 세터를 활용하는 이유가 은닉화이기 때문에 변수 앞에 #을 붙혀서 은닉화할 수 있다.

class Car {
  #name = '';
  
  constructor(name, date) {
    this.name = name;
    this. date = date;
  }
  
  get name() {
    return this.#name
  }
  
  set name(newName) {
  	this.#name = newName;
  }
}

const car = new Car('가브리엘');
console.log(car); // Car {} 은닉화 중이라 안보임
console.log(car.name) // 가브리엘

클래스 상속

프로토타입 상속과 클래스 상속은 명백하게 다른 개념이다.

prototype - 자바스크립트의 객체에 기본적으로 상속을 해주기 위함
classes - 상속을 통해 기존 클래스를 확장하여 새로운 클래스로 정의하기 위함

상속을 하는 부모 클래스, 받는 자식클래스가 계층구조로 이루어져 있다.

Class Vehicle {
  constructor(name) {
  	this.name = name;
    this.position = 0;
  }
  
  move() {
  	this.position += 1;
  }
}

Class Car extends Vehicle {
  honk() {
  	console.log(`${this.name} : ${'빵'.repeat(this.position)}`);
  }
}

const car = new Car('가브리엘');
console.log(car); // Car { name: '가브리엘', position: 0}

car.move()
car.move()
car.move()
console.log(car); // Car {name : '가브리엘', position: 3}

car.honk(); // 가브리엘 : 빵빵빵

console.log(car instanceof Car); //true
console.log(car instanceof Vehicle) //true

Car 클래스에서 정의한 적이 없지만 다 알고있다.
car 인스턴스는 Car의 인스턴스이자 Vehicle의 인스턴스이다.

super(생성자 호출)

생성자 메서드에서 super 키워드를 호출하면 수퍼(부모)클래스에 있는 생성자를 호출한다.

Class base {
  constuctor(a, b) {
  	this.a = a;
    this.b = b;
  }
}

class Derived extends base {
  constructor(a,b,c) {
  super(a,b)
  this.c = c;
  }
}

const derived = new Derived(1, 2, 3);
console.log(derived); // Derived { a: 1, b: 2, c: 3 }

자식 클래스에 constructor가 없으면 암묵적으로 contructor에 super가 활성화 되어 부모클래스의 constructor에 전달된다.
super 키워드는 오직 자식만 사용할 수 있다.

super (메서드 참조)

메서드가 바인딩된 객체(수퍼클래스의 prototype 프로퍼티에 바인딩 된 프로토타입)여야 참조가 가능

class Base {
  constructor(name) {
  	this.name = name;
  }
  
  sayHi() {
  	return `Hi${this.name}`;
  }
}

class Derived extends Base {
  sayHi() {
  	return `${super.sayHi()}`;
  }
}

const derived = new Derived('가브리엘');
console.log(derived.sayHi()); // Hi가브리엘

상속 클래스의 인스턴스 생성 과정

new 키워드 -> 자식 -> 부모 -> 인스턴스가 전달 후 위에서 아래로 다시 흐르며 반환해준다.

profile
개발자 지망생

0개의 댓글

관련 채용 정보