프로그래밍 공부하기

객체지향프로그래밍의 특징 본문

Web/[JS] Common

객체지향프로그래밍의 특징

ihl 2021. 1. 14. 17:35

2021/01/14 - [Javascript/Basic JS] - 객체 지향 프로그래밍(Object Oriented Programming)

이전 포스팅에 이어 객체지향프로그래밍의 특징에 대해 알아보자.

 

3. 객체 지향 프로그래밍의 특징

  객체지향프로그래밍은 크게 4가지의 특성이 있다.

 1) 캡슐화(Encapsulation)

class Circle{
  constructor(radius, color){
    this.radius = radius;
	this.color = color
  }
  expendRadius(){
    this.radius += 1
  }
}

let c1 = new Circle(4, "red"); //반지름이 4이고 빨간색인 원
let c2 = new Circle(7, "blue"); //반지름이 7이고 파란색인 원
c1.expendRadius(); //c1의 반지름이 4에서 5로 확대
c1.expendRadius(); //c1의 반지름이 5에서 6으로 확대
c2.expendRadius(); //c2의 반지름이 7에서 8으로 확대

   캡슐화는 특정한 목적을 위해 관련된 기능과 특성을 한 곳(캡슐)에 모아 사용하는 것이다. 즉, 어떤 목적을 위해 만들어진 클래스(캡슐)에 관련된 속성(데이터)과 기능(메소드)들을 모아 넣는 것이다.

   프로그램상에 원 그리기를 구현하려면 어떻게 해야할까? 먼저 원을 하나의 객체로 잡고 실제 원을 찍어낼 틀인 클래스를 작성해야한다. 다음으로 캡슐화를 구현한다. 프로그램을 통해 그려질 모든 원이 갖고있는 특징인 radius(반지름)과 color(원 색깔)를 속성으로 만들 수 있다. 또한 그려진 원을 확대할 수 있는 기능을 expendRadius라는 메소드로 구현하고 Circle 클래스에 넣을 수 있다. 이렇게 만들어진 class에 대해 new 키워드를 사용하여 실제 객체(원)을 만들 수 있다.

  캡슐화를 통해 관련된 기능과 특성을 클래스라는 곳에 모아 코드를 한 번 작성하고 객체를 여러 개 찍어낼 수 있으며, 객체의 동작도 클래스 내에 만들어진 메소드를 통해 실행된다. 즉, 하나의 코드를 객체를 다룰 때마다 재활용할 수 있다. 또한 기능이나 속성에 변동사항이 있을 때도 클래스만 변경하면 해당 클래스로부터 만들어진 모든 객체에 일괄 적용된다.

 

 2) 추상화(Abstraction)

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort(); //["Dec", "Feb", "Jan", "March"]

   프로그래머가 생성된 객체의 메소드를 사용할 때 메소드 내에 어떤 복잡한 로직이 들어가야하는지 알 필요가 없이 사용방법에 따라 사용하기만 된다는 것이다.

  Array.prototype.sort()를 사용할 때 메소드 내에서 무엇을 기준으로 어떤 방식으로 정렬을 수행하는지 구체적으로 알지 못한다. 그러나 sort()의 호출방법만 알면 sort()메소드를 사용할 수 있다. 이러한 특성이 추상화이며 이를 통해 프로그래머들은 객체들을 더 쉽게 사용할 수 있다.

 

 3) 상속(Inheritance)

class Animal{
  constructor(name, age, food){
    this.name = name;
	this.age = age;
	this.food = food;
  }
  cry(){
    console.log("...");
  }
}

class Tiger extends Animal{
  constructor(name, age){
    super(name, age, "고기")
  }
  cry(){
    console.log("어흥");
  }
}

   객체들은 구현할 때 서로 포함관계를 가져야할 때가 있다. 이러한 경우 부모(상위) 클래스에서 구현한 속성과 메소드들을 자식(하위) 클래스가 그대로 사용할 수 있도록 상속받는 형태로 구현할 수 있다.

  예를 들어 동물원 관리 시스템을 구현하기 위해 Animal이라는 객체를 만들었다 생각해보자. Animal들은 name, age, food 등의 속성이 존재하며 cry(울음소리내기)라는 동작을 수행한다. 이 상황에서 Tiger이라는 객체를 만들어 보자. 호랑이는 동물의 한 종류이며 호랑이에게도 이름과 나이, 먹이가 있고 울음소리 내기 동작을 수행할 수 있다. 다만 먹이가 고기이며 울음소리가 '어흥'이라는 것 등의 디테일한 차이만 있을 뿐이다. 이러한 경우 새로운 Tiger라는 클래스를 만들기 보다는 Animal이라는 클래스를 상속하여 Animal에 이미 존재하는 속성과 메소드를 가져오고 디테일한 부분만 따로 지정하여 보다 효율적으로 클래스를 작성할 수 있다.

  상속을 통해 클래스를 정의하면 중복되는 부분의 코드를 다시 작성할 필요가 없이 한 번만 코드를 작성하면 된다. 또한 객체 속성이나 메소드에 수정사항이 생겼을 때도 코드가 정의된 한 곳만 수정하면 모든 객체에 일괄 적용된다.

 

 4) 다형성(Polymorphism)

   하나의 클래스, 메소드가 상황에 따라 다양한 방식으로 동작할 수 있다는 것이다. 대표적인 예로 오버라이딩과 오버로딩이 있다.

  ○오버라이딩

class Animal{
  constructor(name, age, food){
    this.name = name;
    this.age = age;
    this.food = food;
  }
  cry(){
    console.log("...");
  }
}

class Tiger extends Animal{
  constructor(name, age){
    super(name, age, "고기")
  }
  cry(){
    console.log("어흥");
  }
}

class Sparrow extends Animal{
  constructor(name, age){
    super(name, age, "지렁이")
  }
  cry(){
    console.log("쨱쨱");
  }
}

       오버라이딩은 부모 클래스에서 상속받은 속성과 메소드를 자식 클래스에서 재정의하여 덮어쓰기 하는 것이다.

       오버라이딩의 예시는 이미 상속부분에서 살펴보았다시피 Animal의 cry() 메소드를 동물별로 각각 다른 울음소리를 내도록 자식 클래스들에서 재정의하는 것이다. 이 때 재정의된 데이터는 덮어쓰기 되므로 Tiger나 Sparrow의 cry() 메소드가 부모의 것도 포함하여 2개가 되는 것이 아니라 재정의한 메소드 하나로 된다.

 

  오버로딩

      오버로딩은 매개변수 갯수, 종류에 따라 같은 함수지만 다른 동작을 취하는 것이다. JavaScript의 경우 함수 매개변수를 자유롭게 사용할 수 있기 때문에 같은 이름의 함수를 여러개 지정하여 오버로딩하지 않는다. 단, 함수 내부에서 매개변수의 종류나 갯수에 따라 분기하여 처리할 수 있으며 이를 다형성이라고 할 수 있는 것 같다.(참고)

'Web > [JS] Common' 카테고리의 다른 글

Instantiation Patterns  (0) 2021.01.14
프로토타입  (0) 2021.01.14
객체 지향 프로그래밍(Object Oriented Programming)  (0) 2021.01.14
함수 내의 this 지정: call, apply, bind  (0) 2021.01.13
화살표 함수  (0) 2021.01.12
Comments