CS와 Node.js 5. 객체지향 JS, 클래스/인스턴스, 상속, 다형성, SOLID 원칙

박재하·2023년 11월 3일
0

CS와 Node.js

목록 보기
5/12

클래스, 오브젝트, 인스턴스

[Java] 클래스, 객체, 인스턴스의 차이

[Java] 클래스, 객체, 인스턴스의 차이 - Heee's Development Blog

객체(오브젝트, Object)

  • 객체(Object)는 객체지향 프로그래밍 패러다임에서 자신 고유의 값과 동작을 가지는 물리적, 추상적인 모든 대상을 일컫는다.
  • 개발에서는 일반화적으로 고유의 (속성, 변수), 동작(메서드, 함수)을 가지고 있는 것(추상적인 의미)들을 의미한다.
  • 본 미션의 울트론에 비유한다면 속성은 HP이나 공격력, 동작은 이동이나 공격이 될 수 있다. 울트론이라는 종(species)이 객체라고 볼 수 있다.

클래스

  • 클래스(Class)는 객체지향를 실제로 구현하기 위한 설계도 또는 을 말한다.
  • 개발에서는 객체가 가지는 속성동작필드메서드로 각각 실제로 정의해놓은 정의된 구조체를 의미한다.
  • 본 미션의 울트론에 비유한다면 HP, 공격력, 이동, 공격 등의 내부 변수/상수를 명세해놓은 Class 정의가 클래스라고 볼 수 있다.

인스턴스

  • 인스턴스(Instance)는 클래스라는 “틀”을 통해 실제로 생성된 객체 하나하나를 의미한다.
  • 프로세스 가상 메모리의 Heap 영역에 실제로 클래스에서 정의된 명세에 맞게 메모리가 할당되며, 추상적인 객체를 구현한 실체라고 볼 수 있다.
  • 본 미션의 울트론에 비유한다면 new Ultron()을 통해 실제로 생성한 유닛 하나하나를 의미한다. 본 미션에서는 6개의 울트론 인스턴스가 생성되었다.

객체지향의 여러 개념

상속과 다형성

7. 상속과 다형성

[Java] 상속과 다형성 (Polymorphism)

상속

  • 상속(Inheritance)은 새 클래스를 정의할 때, 기존에 정의해놓은 특정 클래스에서 멤버를 물려받아 생성하는 행위를 칭한다.
  • 자바스크립트에서는 class A {} 선언 후 class B extends A {} 로 클래스 B를 정의하면 기존 멤버 변수 및 상수를 동일하게 사용할 수 있다.
  • 부모 클래스의 함수(메서드)를 변형해서 사용하려면 동일한(선언부도 일치 필요) 함수명을 사용하면 부모 클래스의 함수가 아닌 자식 클래스 고유의 함수를 사용할 수 있다. 이를 오버라이딩이라 한다.

다형성

  • 다형성(Polymorphism)동일한 타입을 사용하지만 다양한 결과가 나오는 성질을 의미한다.
  • 상속된 클래스들을 인스턴스화하여 사용할 때, 부모 클래스에서 상속 후 오버라이딩속성(Property)이나 메소드(Method)를 하나의 형태(부모 클래스에서 정의한 이름)로 접근해서 사용하기 위한 개념이다.
  • 다음과 같이 사용할 수 있다.
class Animal {
  toString() {
    return "";
  }
}

class Lion extends Animal {
  toString() {
    // toString 오버라이딩
    return "사자";
  }
}

class Husky extends Animal {
  toString() {
    // toString 오버라이딩
    return "허스키";
  }
}

class Master {
  feed(animal) {
    console.log(animal.toString(), "에게 먹이를 줬다!");
  }
}

lion = new Lion();
husky = new Husky();
master = new Master();
master.feed(lion); // 사자 에게 먹이를 줬다!
master.feed(husky); // 허스키 에게 먹이를 줬다!

클래스 vs. 프로토타입

10. 프로토타입과 클래스 · GitBook

프로토타입

  • 객체 생성자 함수 아래에 .prototype.[key] = …를 입력하여 설정할 수 있으며, 메서드속성처럼 동작한다.
function Animal(type, name, sound) {
  this.type = type;
  this.name = name;
  this.sound = sound;
}

Animal.prototype.say = function () {
  console.log(this.sound);
};
Animal.prototype.sharedValue = 1;

function Dog(name, sound) {
  Animal.call(this, "개", name, sound);
}
Dog.prototype = Animal.prototype;

function Cat(name, sound) {
  Animal.call(this, "고양이", name, sound);
}
Cat.prototype = Animal.prototype;

const dog = new Dog("멍멍이", "멍멍");
const cat = new Cat("야옹이", "야옹");

dog.say(); // 멍멍
cat.say(); // 야옹

console.log(dog.sharedValue); // 1
console.log(cat.sharedValue); // 1
  • 위 예제와 같이 .prototype을 할당해주면 상속받는 효과를 줄 수 있다.

클래스, 프로토타입

  • JS는 ES5까지 클래스 문법이 따로 없었기 때문에 위에서 작성한 코드처럼 프로토타입을 이용하여 객체 상속을 구현해서 사용했다.
  • 하지만 ES6부터는 class 문법추가되었기 때문에, 같은 효과인 class 문법을 더 권장한다.

this vs. super

Java에서 this와 super 키워드의 차이점

super - JavaScript | MDN

  • this 키워드는 현재 클래스의 참조를 가리키며, super키워드는 부모 클래스의 참조를 가리킨다.
  • super()는 함수 형태 호출해야 하며 부모 클래스의 생성자 함수를 호출하여 넘겨주면 현재 클래스의 속성처럼 사용할 수 있다. super() 호출 위에 this 키워드가 사용되어서는 안된다.
  • Javascript에서의 활용 예시는 다음과 같다.
class Polygon {
  constructor(height, width) {
    this.name = "Polygon";
    this.height = height;
    this.width = width;
  }
}

class Square extends Polygon {
  constructor(length) {
    // this.height; // 참조오류가 발생. super가 먼저 호출되어야 함.

    // 여기서, 부모클래스의 생성자함수를 호출하여 높이값을 넘겨줌.
    // Polygon의 길이와 높이를 넘겨줍니다.
    super(length, length);

    // 참고: 파생 클래스에서 super() 함수가 먼저 호출되어야
    // 'this' 키워드를 사용할 수 있습니다. 그렇지 않을 경우 참조오류가 발생합니다.
    this.name = "Square";
  }

  get area() {
    return this.height * this.width;
  }

  set area(value) {
    this.area = value;
  }
}

SOLID 원칙

SOLID (객체 지향 설계)

SOLID 원칙

  • SOLID 원칙은 객체지향 설계의 5대 원칙이라고 불리며, 각각 SRP, OCP, LSP, ISP, DIP의 앞글자를 따서 SOLID 원칙으로 불린다. 표로 정리하면 다음과 같다.
두문자약어개념설명
SSRP단일 책임 원칙 (Single responsibility principle)- 한 클래스는 하나의 책임만 가져야 한다.
OOCP개방-폐쇄 원칙 (Open/closed principle)- “소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.”
LLSP리스코프 교환 원칙 (Liskov substitution principle)- “프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.”
IISP인터페이스 분리 원칙 (Interface segregation principle)- “특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.”
DDIP의존관계 역전 원칙 (Dependency inversion principle)- 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”
- 의존성 주입은 이 원칙을 따르는 방법 중 하나다.

단일 책임 원칙 (Single responsibility principle)

  • 모든 클래스는 각각 하나의 책임만 가져야 한다.
  • 클래스는 그 책임을 완전히 캡슐화해야 한다는 의미이다.
  • 따라서 해당 클래스가 책임지고 있는 기능문제가 발생했을 때는, 온전히 해당 클래스만 수정해서 그 문제를 해결할 수 있어야 한다.

리스코프 교환 원칙 (Liskov substitution principle)

  • 자식 클래스는 언제나 부모 클래스를 대체할 수 있다.
  • 부모 클래스가 들어갈 자리에 자식 클래스를 넣어도 잘 작동해야 한다는 의미.
  • 따라서 자식 클래스의 정의 시, 상속한 부모 클래스의 책임을 무시하거나 재정의하지 않고 확장만을 수행하도록 해야 한다.
profile
해커 출신 개발자

0개의 댓글