JavaScript

[JS기초] 객체 지향 프로그래밍

염두리안 2024. 11. 11. 15:10
728x90
반응형

객체 지향 프로그래밍

  • 추상화 : 어떤 구체적인 존재를 원하는 방향으로 간략화해서 나타내는 것
    • 주의 : 클래스, 프로퍼티, 메서드 이름을 잘 지어야 함... 직관적이고 쉽게
  • 캡슐화 : 객체의 특정 프로퍼티에 직접 접근하지 못하도록 막는 것 ~> 특정 메서드를 통해 접근함
    • 프로그래밍에서 보통 숨기고자 하는 프로퍼티 앞에 언더바(_)를 붙임 | ex. _name
    • JS에선 캡슐화를 자체적으로 지원하는 문법은 아직까진 없다... (자바의 경우 private를 통해 지원)
class User {
  constructor(email, birthdate) {
    this.email = email;
    this.birthdate = birthdate;
  }
  buy(item) {
    console.log(`${this.email} buys ${item.name}`); 
  }

  get email() { // 프로퍼티를 읽는 용도
    return `Email Address is ${this._email}`;
  }

  set email(address) { // 이메일 값이 맞는지 확인
    if (address.includes('@')) {
      this._email = address;
    } else {
      throw new Error('invalid email address');
    }
  }
}


const item = {
  name: '스웨터',
  price: 300000,
};

const user1 =  new User('christ1234@google.com', '1992-03-21');
user1.email = 'chirs_robert@google.com';
console.log(user1.email);
  • 상속 : 하나의 객체가 다른 객체의 프로퍼티와 메서드를 물려 받는 것 → 코드의  재사용성이 늘어남
    • 코드의 공통적인 부분이 있다면 코드 길이가 길어지거나 한쪽만 수정시 오류 발생 가능성 有 ~> 상속을 통해 해결
    • Class [자식클래스] extends [부모클래스]
    • Super 생성자 : 부모 클래스 안에 있는 생성자를 의미... 자식 클래스에서 객체를 만들 때, 생성자 안에서 super를 호출 후 부모 클래스에 있는 생성자 함수를 먼저 호출해야 함.
class User { // 부모 클래스
  constructor(email, birthdate) {
    this.email = email;
    this.birthdate = birthdate;
  }
  buy(item) {
    console.log(`${this.email} buys ${item.name}`); 
  }
}
// User 클래스를 상속 받음.. 겹치는 변수는 생략
class PremiumUser extends User { // 자식 클래스
  constructor(email, birthdate, level) {
    super(email, birthdate); // super 키워드를 통해 부모클래스로부터 호출
    this.level = level;
  }
  streamMusicForFree() {
    console.log(`Free music streaming for ${this.email}`);
  }
}
  • 다형성 : 많은 형태를 갖고 있는 성질 | 하나의 변수가 다양한 종류의 객체를 가리키는 것
    • 오버라이딩(overriding) : 자식클래스에서 부모클래스와 동일한 메서드를 정의하고, 그 내용을 다르게 채우는 것
class User {
  constructor(email, birthdate) {
    this.email = email;
    this.birthdate = birthdate;
  }
  buy(item) {
    console.log(`${this.email} buys ${item.name}`);
  }
}

class PremiumUser extends User {
  constructor(email, birthdate, level) {
    super(email, birthdate);
    this.level = level;
  }
  buy(item) { // 일반 유저의 buy 메시지와 다르게 출력
    console.log(`${this.email} buys ${item.name} with a 5% discount`);
  }
  streamMusicForFree() {
    console.log(`Free music streaming for ${this.email}`);
  }
}
  • 부모클래스의 일반 메서드를 호출하고 싶을 때도 super 키워드 사용 가능
class User {
  constructor(email, birthdate) {
    this.email = email;
    this.birthdate = birthdate;
  }
  buy(item) {
    console.log(`${this.email} buys ${item.name}`);
  }
}

class PremiumUser extends User {
  constructor(email, birthdate, level, point) {
    super(email, birthdate);
    this.level = level;
    this.point = point;
  }
  buy(item) {
    super.buy(item); // console.log(`${this.email} buys ${item.name}`); 출력
    this.point += item.price * 0.05;
  }
  streamMusicForFree() {
    console.log(`Free music streaming for ${this.email}`);
  }
}
  • instanceof 연산자 : 현재 가리키는 객체가 어느 클래스에서 만든 객체인지 확인하고 싶을 때 사용
    • 자식클래스에서 만든 객체는 부모클래스에서 만든 객체로 인정됨.
users.forEach((user) => {
  //console.log(user instanceof PremiumUser);
  console.log(user instanceof User);
});
  • static 프로퍼티와 static메서드 : 클래스 자체에 소속되는 프로퍼티와 메서드... 객체에 직접 소속되는 것이 아닌 클래스 자체로 접근
class Math{ // 원주율과 넓이를 구하는 클래스
	static PI = 3.14;
    static getCircleArea(radius){
    	return Math.PI & radius * radius;
    }
}
Math.PI = 3.141592; // Static 메서드는 변경 가능

// 클래스 이름으로 바로 접근
console.log(Math.PI);
console.log(Math.getCircleArea(5));
  • 실무에선 클래스는 각 클래스와 메인로직을 파일별로 쪼개서 작성함! (한 파일에 여러 개 클래스 X)
728x90
반응형