자바스크립트 객체 지향이란(OOP)

JGwon·2023년 10월 2일
1

프로그래밍

목록 보기
3/4

객체지향 프로필사진
자바스크립트는 멀티 패러다임 언어로 명령형, 함수형, 프로토타입 기반 객체 지향 언어다. 비록 다른 객체지향 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력들을 지니고 있다, 간혹 클래스가 없어서 객체 지향이 아니라고 생각하는 사람들도 있으나 프로토타입 기반의 객체지향 언어이다.

다른 언어들과 다른 점이 있었으니..
C++, JAVA: Class 기반 언어
Javascript: Prototype 기반 언어

프로토타입이란?

  • 프로토타입은 '원형'이라는 의미를 갖고 있습니다. Javascript에서 객체를 만드는 행위는 이 프로토타입을 기술을 응용해서 만들어지는 것인데요. ES6에서 도입된 class 기술도 사실은 다른 언어처럼 오리지널 class를 만든 것이 아니고, 프로토타입으로 class기술을 재현한 것이라고 보면 되겠습니다.
    (* 자세한 내용은 검색하시거나, 코어자바스크립트라는 책을 읽으면 도움 될 것입니다."

💡 자, 그럼 자바스크립트에서 객체를 만들려면 어떤 방법이 있을까요?

// 1. 생성자 함수
function F() {}
var obj1 = new F();
obj1.name = 'Lee';

// 2. class
class Animal {
  constructor(name,weight){
    this.name = name; 
    this.weight = weight;
	}
	
  // 필요한 메서드를 정의
  eat() {...}
}
  const pig = new Animal('pig', 60);

// 3. Object() 생성자 함수
var obj2 = new Object();
obj2.name = 'Lee';

// 4. 객체 리터럴
var obj3 = {};
obj3.name = 'Lee';

이 모든 방식이 프로토타입의 상속과 관련되어 있습니다. 생성자 함수, class를 프로토타입(원형)이고, 프로토타입을 상속해서 만들어진 객체 obj3, pig를 인스턴스라고 부릅니다.

붕어빵
생성자 함수와 class는 틀... 예를 들어 붕어빵 틀 이고,
만들어진 인스턴스(객체)를 붕어빵에 비유하는게 좋겠습니다.
참고자료 - 제로초님 글




🔙 객체 지향 프로그래밍의 등장과 이전의 이야기(객체가 왜 생겼을까?)

teo님의 글을 참고해주세요


그래서 객체지향이 뭐야?

객체 지향은 객체안에서 상태(속성)를 나타내는 변수들과 객체의 행동(메서드)으로 이루어져 있고, 각각의 객체들은 협력하는 과정을 통해서 대규모 소프트웨어를 만듭니다. 객체지향은 객체들간의 협력, 메시지, 책임이 중요하다.
즉 객체 지향 프로그래밍 (Object-Oriented Programming, OOP)은 프로그래밍에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체로 만들고, 객체들간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.




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

객체 지향 프로그래밍은 크게 추상화, 캡슐화, 상속, 다형성의 네가지 특징을 가지고 있습니다.

1. 추상화

참고사진

  • 객체에서 공통된 속성과 행위를 추출하는 것
  • 공통된 속성과 행위를 찾아서 타입을 정의하는 것
  • 추상화는 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단하게 만드는 것
// 음료 객체
class Beverage {
  constructor(props) {
    this.state = {
      amount: 0.5,
    };
  }

  drunk() {
    this.state = { ...this.state, amount: 0 };
  }
}

// -> 음료 객체에 많은 상태와 기능들이 있지만 필요한 기능들만 간소화한 생테

지인과의 대화를 예를 들어보자.
1. 지인: "야 오랜만이다. 나 이번에 야먀하의 어떤 모델 피아노와 삼익의 어떤 모델 피아노, 스타인웨이 피아노, 가와이 피아노, 영창 피아노... //생략
~중에 고급지고 연주하기에도 편하고 소리도 맑은 스타인웨이 피아노로 샀어!!
2. 나: 와 그래..?(듣느라 벌써 지침) 좋은 피아노 샀네~! 나도 한 번 연주해 볼 기회를 줘~

여러분이 피아노에 관심이 있었다면 모르겠지만, 관심이 전혀 없다면 친구의 얘기에 애매한 반응을 하거나 재밌는 얘기는 아니라고 생각 확률이 높을 수 있겠습니다. 혹시 이렇게 생각할 수도 있겠죠
"뭐.. 그냥 다 같은 피아노아니야?



타인과의 대화를 할 때 우리는 추상화를 많이 사용한다고 하네요. 인간의 뇌는 단순한 걸 좋아하거든요. 앞선 예시를 조금 바꿔보겠습니다.

  1. 지인: 나 이번에 스타인웨이 그랜드 피아노샀자나, 너무 좋아 ㅠㅠ
  2. 나: 정말? 그 피아노 가격도 비싸고 소리도 좋기로 정평이 나 있고, 외관도 삐까뻔쩍(?)하자나? 전문가용 피아노 아니야? 와 정말 부럽다~~😏

신기하게도 스타인웨이 그랜드 피아노 만으로도 어떤 특징들을 갖고 있는지 단번에 파악하기가 수월합니다.


참고
여러분은 피아노🎹를 생각하면 어떤 모양을 생각하시나요? 대체로 그랜드 피아노, 업라이트 피아노를 떠올릴 것입니다. 이 또한 추상화입니다.


추상화란 객체에서 공통된 속성행위를 추출하는 것

여기서 객체란 인간이 느끼고 인식할 수 있는 모든 것을 말함. (잠시만 여러분 주위를 둘러보세요. 여러분의 눈에 보이는 모든 것들 그리고 독자께서 인지할 수 있는 모든 것들이 객체입니다)




2. 캡슐화

  • 외부에서 알 필요 없는 것들은 숨겨 놓자!
  • 외부에 노출해야 하는 값과 내부에서만 사용하는 값을 구분하는 기능이다.
  • 객체가 맡은 역할을 수행하기 위해 관련 상태와 메서드를 묶는 행위
  • 객체 내 상태 데이터가 외부에서 접근이 불가능하고 오로지 함수를 통해서만 접근해야하는 데 이를 바로 캡슐화라고 한다.
class Yamaha {
	#name = 'YAMAHA'
	#price = 20000$
    color = 'black'
    
    play() {...}
}

// object
let yamaha = new Yamaha();

yamaha.color = 'black' // public한 필드는 외부에서 수정이 가능한 잠재적 위험이 있어서 개인정보 같은 중요정보나 외부에서 접근하면 안되는 프로퍼티에는 캡슐화가 필수이다.

yamaha.name = 'YoungChang'; //  Error TS18013: Property '#name' is not accessible outside class 'Human' because it has a private identifier.    

은닉을 향한 자바스크립트의 여정

javascript에서는 캡슐화를 위한 private 변수는 제공하지만 protected 변수는 제공하지 않습니다. 따라서 protected 변수 구현을 위해 변수명 앞에서 _표시를 해주어 protected 변수를 표시합니다.
자바스크립트에서 private와 protected 사용법




3. 상속

  • extends를 사용함.
  • 상위 클래스의 속성을 하위 클래스에게 물려주는 것을 의미함.
  • 상속을 통해서 기존 코드를 재사용, 확장 가능함.
장점단점
재사용으로 인한 코드가 줄어든다상위 클래스의 변경이 어려워진다
범용적인 사용이 가능하다불필요한 클래스가 증가할 수 있다
자료와 메서드의 자유로운 사용 및 추가가 가능하다상속이 잘못 사용될 수 있다

상속추상화를 통해서 객체의 일부분을 재사용을 하는 방법을 찾게 되었습니다.




4. 다형성

  • 같은 메서드를 호출하더라도 객체에 따라 다르게 동작하는 것
  • 대표적으로 재정의(Overiding)으로 구현 가능하다.

반에 있는 친구들에게 '안녕?'이라고 인사하면 친구들 각각의 반응이 모두 다를 것이다.
객체의 다형성도 마찬가지다. 객체의 다형성이란 객체들마다 다르게 동작하는 것을 말한다.

javascript는 java와 달리 interface에 대한 기능을 제공하지 않는다.

class Animal {
  constructor(sound) {
  	this.sound = sound;
  }
  
  move() {
  	console.log('동물이 움직여요');
  }
}

class Cat extends Animal {
	constructor(sound){
    	super(sound);
      	this.move();
    }
  
  move() {
  	console.log(`동물이 ${sound} 움직여요`);
  }
}
let animal = new Animal();
let cat = new Cat(); // 동물이 움직여요
let cat2 = new Cat('재빠르게');
animal.move(); // 동물이 움직여요
cat2.move() // 동물이 재빠르게 움직여요





// 제로초님
var Animal = function() {
};
Animal.prototype.move = function() {
  console.log('동물이 움직여요');
};

var Cat = function() {
  Animal.apply(this, arguments); // 속성 상속받는 방법
}
Cat.prototype = Object.create(Animal.prototype); // 프로토타입 상속 방법
Cat.prototype.constructor = Cat; // 버그 패치

console.log(new Animal().move()); // 동물이 움직여요
console.log(new Cat().move()); // 동물이 움직여요

Cat.prototype.move = function(sound) { // 오버라이딩
  console.log(sound + ' 움직여요');
  return '야옹';
};

console.log(new Cat().move('살금살금')); // 살금살금 움직여요

제로초님의 예시를 가져왔다 (한 번 쭉 읽어보고 오버라이딩에 대해 이해해보자.)


근데 오버라이딩은 뭘까?

  • 오버라이딩은 상위 클래스에서 가져온 메서드를 재정의해서 하위 객체의 특성에 맞게 변형하는 것을 말한다.
  • 부모 객체의 메소드를 덮어씌운 것입니다.
  • 부모 클래스에서 이미 정의된 함수 등을 자식 클래스에서 같은 이름으로 사용하되 안에 들어가는 내용(기능, 속성 등)을 바꿔서 사용

오버로딩은 하나의 함수를 유연하게 활용하고 싶을 때 사용

오버라이딩과 오버로딩




🔚 끝으로

객체지향과 함수형 프로그래밍을 공부하면서 자바스크립트에서 둘을 조화롭게 사용할 수 있다면 프로그래밍 능력을 한 층 더 끌어올릴 수 있지 않을까 란 생각을 해보게 됐습니다.
자바스크립트는 멀티 패러다임 언어인만큼 객체지향과 함수형을 조화롭게 사용하는 것이 js를 잘 다루는 개발자라고 볼 수 있겠습니다.

데이터와 메소드를 통해 독립적인 작은 프로그램으로써 만들어 편리하게 재사용하는 장점을 취하되 객체들의 결합도가 높아져서 프로그램이 복잡해지지 않도록
객체로 만들지 않아도 되는 부분은 함수형으로 만들어서 코드의 덩치가 커져도 유지보수하기 좋게 재사용이 편리한 코드를 만들어 내는 것이 js를 잘하는 것이라고 할 수 있겠습니다.

💚참고자료

teo님의 객체지향
객체지향 프로그래밍에 대해

profile
하루에 한 가지의 변화를 만들자.

0개의 댓글