티스토리 뷰

개발/TIL

객체지향 프로그래밍

hahagarden 2023. 3. 15. 17:53

프로그래밍 패러다임

출처 구글이미지

건물을 지을 때에 다양한 건축공법이 있다. 프로그래밍에도 어떻게 프로그램을 작성할 것인지 방법들이 여러 가지 있는데, 프로그래밍 패러다임이라고 부른다.
프로그래밍 패러다임에는 함수형 프로그래밍, 절차 지향 프로그래밍, 객체 지향 프로그래밍 등이 있다.
오늘은 객체 지향 프로그래밍에 대해서 알아보자.

 

객체 지향 프로그래밍

출처 코드스테이츠 학습자료

객체 지향 프로그래밍은 하나의 청사진을 만들고 그 청사진으로 객체를 만드는 방법이다. 이 때, 이 청사진을 클래스, 청사진으로 만든 객체들을 인스턴스객체 또는 인스턴스라고 부른다.

 

function Monster(name, hp, att, xp) {
  this.name = name, 
  this.hp = hp, 
  this.att = att, 
  this.xp = xp;
}
Monster.prototype.attack = function (monster) {
  monster.hp -= this.att;
};
Monster.prototype.heal = function (monster) {
  this.hp += 20;
};
const monster1 = new Monster("괴물1", 50, 5, 0);
const monster2 = new Monster("괴물2", 50, 5, 0);
monster1.attack(monster2);
console.log(monster1, monster2);

ES5로 클래스를 만든 예이다. Pascal Case로 클래스명을 짓고 function 키워드로 함수를 만든다. this는 각각의 인스턴스에 바인딩된다. 메소드는 클래스명.prototype.메소드명에 함수를 할당함으로서 정의할 수 있다.

 

class Monster {
  constructor(name, hp, att, xp) {
    this.name = name, 
    this.hp = hp, 
    this.att = att, 
    this.xp = xp;
  }
  attack(monster) {
    monster.hp -= this.att;
  }
  heal(monster) {
    this.hp += 20;
  }
}
const monster1 = new Monster("괴물1", 50, 5, 0);
const monster2 = new Monster("괴물2", 50, 5, 0);
monster1.attack(monster2);
console.log(monster1, monster2);

 ES6에서 class키워드가 생기면서 위와 같이 클래스를 생성할 수 있다. 생성자에 전달인자를 전달하고 메서드들을 클래스 안에 함께 묶을 수 있다.

 

객체 지향 프로그래밍은 모두 객체로 그룹화된다. 객체 내에는 데이터와 기능이 함께 있다. 이렇게 모든 것을 객체로 구현하여 작성하는 객체 지향 프로그래밍은 크게 캡슐화, 추상화, 상속, 다형성의 4가지 특성이 있다.

 

캡슐화

function makeCounter() { 
  let value = 0; 
  return { 
    increase: function() { value++; }, 
    decrease: function() { value--; }, 
    getValue: function() { return value; } 
  } 
} 

let counter1 = makeCounter(); counter1.increase();
counter1.getValue(); // 1
console.log(counter1.value) // undefined

자바스크립트의 클로저의 활용사례 중 정보 은닉이 있었다. 위 코드도 클로저 패턴으로 변수 value를 보호했다. 숨기고 외부에서 조작할 수 없도록 했다. 객체 지향에서 public, protected, private 접근제어자를 통해 정보를 은닉하곤 하는데, 자바스크립트에는 이 키워드들이 없다. ES2019에 private기능을 하는 #이 등장했지만 자바스크립트로 캡슐화를 완전히 구현하기에는 한계가 있어보인다. 타입스크립트에서 접근제어자를 사용할 수 있다.

 

추상화

출처 코드스테이츠 학습자료, 생활코딩

전화기로 전화를 받고 거는데에는 여러 가지 복잡한 메커니즘이 있다. 하지만 전화기의 외관에는 단순하게 버튼과 수화기만 보인다. 복잡한 정보들은 안으로 숨기고 중요한 키 정보들만 추출하여 밖으로 드러낸 것이다.

오른쪽에 4장의 영국지도가 있다. 주변의 건물들, 도로명, 실제 역의 위치 등을 반영하고 있다. 하지만 이런 세부적인 정보를 다 거두고 이전 역, 다음 역, 환승역인지 여부, 호선 등의 최소한의 중요한 정보에만 집중한 4번째 지도가 가장 사용하기 좋다. 많은 불필요한 정보는 숨기고 필요한 대표적인 정보만 추출하여 적용한 것이다.

 

출처 https://www.codestates.com/blog/content/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8A%B9%EC%A7%95

이처럼 프로그래밍에서도 객체들의 공통적이고 중요한 프로퍼티와 메서드들을 따로 추출하여 추상화를 한다. 위 그림의 Vehicle은 추상클래스이다. 

const vehicle = new Vehicle(); // error
class Abstract {
  constructor() {
    if (new.target === Abstract) {
      throw new TypeError("Cannot construct Abstract instances directly");
    }
  }
}
class Derived extends Abstract {
  constructor() {
    super();
    // more Derived-specific stuff here, maybe
  }
}
const a = new Abstract(); // new.target is Abstract, so it throws error
const b = new Derived(); // new.target is Derived, so no error

추상클래스는 클래스 내에 함수를 구현하는 것이 아니라 위의 코드처럼 선언만 하거나 데이터타입을 정해주기만 한다. 구현은 상속받은 클래스에서 해주는 것이다. 또한 추상클래스로 직접적인 인스턴스를 생성할 수 없다. 자바스크립트에는 추상클래스라는 개념이 따로 없다. 그래서 위처럼 수동으로 추상클래스처럼 만들어 줄 수는 있다.

 

상속

위에서 본 Vehicle과 Car, Motorbike처럼 클래스간 상속이 가능하다. 상속된 클래스는 super class, base class, parent class로 부르고, 상속받아 확장된 클래스를 sub class, derived class, child class라고 한다.

 

다형성

출처 https://www.codestates.com/blog/content/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8A%B9%EC%A7%95

수퍼클래스 Vehicle에 moveForward()와 moveBackward()메서드가 공통적으로 있다. 서브클래스인 Car과 MotorBike는 각각 다르게 구현했다. 이처럼 같은 메서드명을 다르게 구현하여 인스턴스마다 다른 기능을 할 수 있다. 이것을 다형성이라고 한다.

 

회고

프로그래밍의 꽃이라는 객체 지향 프로그래밍을 배웠다. 예전에 숫자 야구 게임을 객체 지향으로 구현을 해보았다. 그때는 참 말그대로 '객체'만 사용하면 되는줄 알고 한 클래스 내에서 메서드들끼리 꼬리에꼬리를 물며 이상한 코드를 짰었다. 오늘 객체 지향 프로그래밍의 특성을 공부하며, 추상화를 시켜서 중복되는 코드를 줄이고 더욱 문맥적으로 적합한 흐름, 상속을 시키고 용도에 맞게 메서드를 다르게 구현해서 다형성을 갖도록 하고, 캡슐화를 시켜서 외부에서 접근하거나 수정할 수 없도록 프로퍼티와 메서드를 보호하는 것들을 고려해야 한다는 것을 알았다. 그리고 이것이 다가 아니라, 객체 지향 프로그래밍에 다양한 패턴이 있다고 한다. 패턴들을 적용시키며 직접 구현하는 연습을 해야 알 것 같다. 그래서 언제 객체 지향 프로그래밍을 하는건가요?라는 질문에는 제로초님과 드림코딩님 모두 여러 가지 프로그래밍 패러다임을 다룰 줄 알고 장단점을 비교해서 프로젝트에 맞게 선택해야 한다고 한다. 리액트, 뷰, 앵귤러 등의 프레임워크/라이브러리를 선택하는 기준도 명확하지 않고 프로젝트에 따라 팀과 협의하여 정하는거라고 하던데. 궁금하다 🤨

어제와 오늘 갑자기 학습난이도가 점프를 해서 따라가기가 버거웠다. 오늘 Presenters에서 객체 지향 프로그래밍에 대해 영어발표하는 날이어서 준비하느라 더 시간이 없었다. 그래도 준비한만큼 잘 전달한 것 같고, 발표준비덕분에 심도있게 공부할 수 있었다. 앞으로도 화이팅!

 

반응형
댓글