클래스 정의

  • 객체를 손쉽게 만들 수 있는 템플릿 객체
  • class 키워드 사용
  • 생성자 함수와 마찬가지로 함수명은 파스칼 케이스 사용
  • 표현식으로도 클래스를 정의할 수 있다.
// 클래스 선언문
class Person {
  // constructor(생성자) : new 키워드로 객체를 생성할 때 호출되는 함수
  // 모든 클래스는 기본적으로 생성자가 들어가 있어야함 그래야 인스턴스를 만들 수 있음
  constructor(name) {
    this._name = name;
  }
  
 // 클래스 내부에서 메소드 생성시 function 키워드 넣으면 안됨!!
// 일반함수나 화살표함수만 사용 가능
  sayHi() {
    console.log(`Hi! ${this._name}`);
  }
}

// 인스턴스 생성
const me = new Person('Lee');
me.sayHi(); // Hi! Lee


// 클래스명 MyClass는 함수 표현식과 동일하게 클래스 몸체 내부에서만 유효한 식별자이다.
const Foo = class MyClass {};

const foo = new Foo();
console.log(foo);  // MyClass {}

new MyClass(); // ReferenceError: MyClass is not defined

인스턴스 생성

  • new연산자와 함께 클래스 이름을 호출하면 클래스의 인스턴스가 생성된다.
//foo는 Foo 클래스의 인스턴스이다.
const foo = new Foo();
//boo는 Foo 클래스의 인스턴스이다.
const boo = new Foo();
// obj는 객체이고, 그 어떤 클래스의 인스턴스도 아니다.
const obj = { name: 'ellie' };

constructor 생성자

  • constructor 는 인스턴스를 생성한다
  • 클래스 필드를 초기화하기 위한 특수한 메서드
  • 인스턴스를 생성할 때 new 연산자와 함께 호출한 것이 바로 constructor이며 파라미터에 전달한 값은 클래스 필드에 할당한다.
  • constructor는 생략 가능하며, 인스턴스 생성 후 프로퍼티를 동적으로 추가해야 한다.
  • ‼️다만 constructor는 인스턴스의 생성과 동시에 클래스 필드의 생성과 초기화를 실행하므로
    초기화 해야 한다면 constructor를 생략해서는 안된다.
// 클래스 선언문
class Person {
  // constructor(생성자). 이름을 바꿀 수 없다.
  constructor(name) {
    // this는 클래스가 생성할 인스턴스를 가리킨다.
    // _name은 클래스 필드이다.
    this._name = name;
  }
}

// 인스턴스 생성
const me = new Person('Lee');
console.log(me); // Person {_name: "Lee"}

class Foo { }

const foo = new Foo();
console.log(foo); // Foo {}

// 프로퍼티 동적 할당 및 초기화
foo.num = 1;
console.log(foo); // Foo { num: 1 }

클래스 필드(= 멤버변수,데이터멤버)

  • ‼️ 클래스 몸체에는 메소드만 선언
  • 클래스 몸체 안의 constructor 함수 안에 클래스필드(=멤버 변수,데이터멤버) 선언
  • 캡슐화된 변수를 말한다.
  • 클래스 필드는 클래스가 생성할 인스턴스를 가르키는 this에 바인딩
  • 이로써 클래스 필드가 생성할 인스턴스의 프로퍼티 또는 정적 프로퍼티가 될 수 있다.
  • 클래스의 인스턴스를 통해 클래스 외부에서 언제나 참조할 수 있다. 즉 언제나 public이다.
  • 생성자 함수에서 this에 추가한 프로퍼티를 클래스 기반 객체 지향 언어에서는 클래스 필드(멤버변수)라고 부른다.
class Foo {
  name = ''; // SyntaxError , 몸체에는 메소드만 선언 가능

  constructor() {} // 생성자 함수 안에 클래스필드 선언해야함!!
}

getter,setter 접근자 프로퍼티

💡getter

  • 클래스 몸체의 메소드 이름 앞에 get키워드 사용
  • 이때 메소드 이름은 클래스 필드(=멤버변수)의 이름처럼 사용됨
  • 다시말해 getter는 호출이 아닌 프로퍼티처럼 참조형식이며, 참조 시 메서드가 호출됨
  • 반드시 무언가를 반환해야 함
class Student {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  get fullName() {
    return `${this.lastName} ${this.firstName}`;
  }
  
const student = new Student('수지', '김');
console.log(student.firstName);	//수지

//fullName은 메서드지만 get키워드를 사용한 메서드 이므로
//✨점표기법을 통해 프로퍼티로써 접근이 가능하다.✨
console.log(student.fullName);	//김 수지

💡setter

  • 클래스 필드에 값을 할당할 때마다 클래스 필드의 값을 조작하는 행위가 필요할 때 사용
  • set키워드 사용
  • 다시말해 setter는 호출이 아닌 프로퍼티처럼 참조형식이며,
  • 할당 시에 메소드가 호출된다.
// 접근자 프로퍼티 (Accessor Property)
class Student {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  get fullName() {
    return `${this.lastName} ${this.firstName}`;
  }

  set fullName(value) {
    console.log('set', value);
  }
}

const student = new Student('수지', '김');
console.log(student.firstName);
console.log(student.fullName);

//fullName에 값 할당시 해당 setter 호출됨
student.fullName = '김철수';

/*
수지
김 수지
set 김철수
Student { firstName: '수지', lastName: '김' }
*/

static 정적 메소드

  • ‼️ 클래스의 인스턴스가 아닌 클래스 이름으로 호출
  • 따라서 인스턴스를 생성하지 않아도 클래스 이름으로 호출 가능함
  • ‼️클래스가 생성한 인스턴스로 접근할 수 없음
  • 정적 메소드는 this를 사용할 수 없으며,
  • 정적 메소드 내부에서 this는 클래스의 인스턴스가 아닌 클래스 자신을 가르킴
class Fruit {
  // static 정적 프로퍼티, 메서드
  static MAX_FRUITS = 4;
  // 생성자: new 키워드로 객체를 생성할때 호출되는 함수
  constructor(name, emoji) {
    this.name = name;
    this.emoji = emoji;
  }

  // 클래스 레벨의 메서드
  static makeRandomFruit() {
    // 클래스 레벨의 메서드에서는 this를 참조할 수 없음
    return new Fruit('banana', '🍌');
  }

  // 인스턴스 레벨의 메서드
  display = () => {
    console.log(`${this.name}: ${this.emoji}`);
  };
}

//✨클래스 이름으로 호출함!!!
const banana = Fruit.makeRandomFruit();
console.log(banana);			//{name:'banana',emoji:'🍌'}
console.log(Fruit.MAX_FRUITS);	//4

//정적메소드 예시
Math.pow();
Number.isFinite(1);

클래스 상속

  • 코드 재사용 관점에서 매우 유용한 것

💡extends 키워드

  • 부모클래스를 상속받는 자식 클래스를 정의할 때 사용

💡overriding 오버라이딩

  • 부모클래스가 가지고 있는 메서드를 하위 클래스에서 재정의 하는 것

💡super 키워드

  • 부모클래스를 참조할때 또는 부모클래스의 생성자를 호출할때 사용
//부모 클래스
class Animal {
  //생성자 함수
  constructor(color) {
    //클래스 필드(=멤버변수)
    this.color = color;
  }
  //메소드1
  eat() {
    console.log('먹자!');
  }
  //메소드2
  sleep() {
    console.log('잔다');
  }
}

//자식클래스1
class Tiger extends Animal {}
//부모클래스를 상속받은 자식클래스의 인스턴스 tiger
const tiger = new Tiger('노랑이');
console.log(tiger);				// Tiger { color: '노랑이' }
//부모클래스에 있는 메서드 참조 가능
tiger.sleep();					//잔다
tiger.eat();					//먹자!

//자식클래스2
class Dog extends Animal {
  constructor(color, ownerName) {
    //부모클래스의 생성자함수 참조
    super(color);
    //자식클래스의 클래스필드 따로 추가
    this.ownerName = ownerName;
  }
  //자식클래스의 메서드 추가
  play() {
    console.log('놀자아~!');
  }

  // ✨오버라이딩 overriding : 덮어씌우기 가능!!✨
  eat() {
    super.eat();
    console.log('강아지가 먹는다!');
  }
}
const dog = new Dog('빨강이', '엘리');
console.log(dog);			// Dog { color: '빨강이', ownerName: '엘리' }
dog.sleep();				//잔다
dog.eat();					//강아지가 먹는다!
dog.play();					//놀자아~!

quiz

  • 정직원과 파트타임직원을 나타낼 수 있는 클래스를 만들어 보자
    직원들의 정보: 이름, 부서이름, 한달 근무 시간
    매달 직원들의 정보를 이용해서 한달 월급을 계산할 수 있다
    정직원은 시간당 10000원
    파트타임 직원은 시간당 8000원

  • ‼️ PAY_RATE static 멤버 필드는 클래스 내부에서만 사용하므로 외부에서 참조할 필요도, 다른값으로도 변경하면 안되기때문에
    static private으로 설정해서 외부에서는 값을 보지도 수정하지도 못하게 캡슐화해준다


class Employee {
  constructor(name, department, hoursPerMonth, payRate) {
    this.name = name;
    this.department = department;
    this.hoursPerMonth = hoursPerMonth;
    this.payRate = payRate;
  }
  calculatePay() {
    return this.hoursPerMonth * this.payRate;
  }
}

class FullTimeEmployee extends Employee {
  static #PAY_RATE = 10000;
  constructor(name, department, hoursPerMonth) {
    super(name, department, hoursPerMonth, FullTimeEmployee.#PAY_RATE);
  }
}
class PartTimeEmployee extends Employee {
  static #PAY_RATE = 8000;
  constructor(name, department, hoursPerMonth) {
    super(name, department, hoursPerMonth, PartTimeEmployee.#PAY_RATE);
  }
}

const ellie = new FullTimeEmployee('엘리', 's/w', 30);
const bob = new PartTimeEmployee('밥', 's/w', 20);
console.log(ellie.calculatePay());
console.log(bob.calculatePay());
profile
냠소현 개발일지

0개의 댓글