목표: 객체지향 프로그래밍에 대해서 살펴보고 javascript로 어떻게 구현할 수 있는지 알아보자.
객체지향이란?
객체지향 프로그래밍은 컴퓨터 프로그래밍의 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉,"객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메세지를 주고받고, 데이터를 처리할 수 있다.
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 쉽게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다. 또한 프로그래밍을 더 배우기 쉽게 하고 소프트웨어 개발과 보수를 간편하게 하며, 보다 직관적인 코드 분석을 가능하게 하는 장점이 있다. ...위키백과
위키피디아의 설명이 자세히 와닿지 않을 수 있으니 예를 들어서 설명하도록 하겠습니다.
키가 130인 엘리스가 0.5L 양을 지닌 음료를 가지고 있다. 이때 엘리스가 음료를 마시게 되면 엘리스의 키가 1이 되버리는 어플리케이션을 만들려고 한다.
위 그림을 설명하기 위해 엘리스 객체와 음료 객체를 코드를 나타내 보겠습니다.
// 음료 객체
class Beverage {
constructor(props) {
this.state = {
amount: 0.5,
};
}
drunk() {
this.state = { ...this.state, amount: 0 };
}
}
// 엘리스 객체
class Ellis {
constructor() {
this.state = {
height: 130,
};
this.beverage = new Beverage(); // 링크
}
drink() {
this.state = { ...this.state, height: 1 };
this.beverage.drunk();
}
print() {
console.log(this.beverage.state);
console.log(this.state);
}
}
// 실행
const ellis = new Ellis();
ellis.drink();
ellis.print();
// { amout : 0 }
// { height : 1 }
엘리스 객체와 음료 객체는 각각 해당 객체의 상태를 나타내는 상태와 객체들의 행동을 나타내는 메서드로 이루어져 있고 엘리스 객체와 음료 객체는 링크를 통해 서로 메세지를 송수신하여 음료를 마시면 엘리스 키가 1이 되어버리는 소프트웨어를 만들 수 있습니다.
좀 더 자세히 설명하자면 객체지향이란 해당 객체의 상태를 나타내는 변수들과 객체의 행동을 나타내는 메서드로 이루어져 있고 각각의 객체들은 협력하는 과정을 통해서 대규모 소프트웨어를 만듭니다. (객체와 객체는 객체 내 메서드를 통해서 메세지를 전송하여 각각의 객체의 상태를 변경하여 협력합니다.)
// 음료 객체
class Beverage {
constructor(props) {
this.state = {
amount: 0.5,
};
}
drunk() {
this.state = { ...this.state, amount: 0 };
}
}
// -> 음료 객체에 많은 상태와 기능들이 있지만 필요한 기능들만 간소화한 생테
캡슐화
라고 한다.javascript에서는 캡슐화를 위한 private 변수는 제공하지만 protected 변수는 제공하지 않습니다. 따라서 protected 변수 구현을 위해 변수명 앞에서
_
표시를 해주어 protected 변수를 표시합니다.
// javascript에서 내장클래스를 확장한 모습
class PowerArray extends Array {
isEmpty() {
return this.length === 0;
}
}
let arr = new PowerArray(1, 2, 5, 10, 50);
alert(arr.isEmpty()); // false
// isEmpty()함수 뿐만 아니라 배열 객체의 내장 메서드도 사용 가능한 모습
let filteredArr = arr.filter(item => item >= 10);
alert(filteredArr); // 10, 50
alert(filteredArr.isEmpty()); // false
Overiding
으로 구현 가능하다. javascript는 java와 달리
interface
에 대한 기능을 제공하지 않는다.
따라서Overiding
을 구현하기 위해서는 아래와 같이 사용 가능하다.
// 상위 클래스 == Interface 클래스
// 하위 클래스에서 Interface 클래스에서 선언한 메서드를 선언하지 않을 시 에러
class MyError {
checkLimit() {
throw new Error("Overiding Error -> 제한된 input 길이를 체크하자");
}
occurError() {
throw new Error("Overiding Error -> Error 발생 시 로직 멈추자");
}
}
class UsersError extends MyError {
constructor(user) {
super();
this.user = user;
this.occurError();
}
checkLimit() {
return 1 <= this.user.length && this.user.length <= 30;
}
checkLower() {
return this.user.match(/[a-z]/g).length === this.user.length;
}
occurError() {
if (!(this.checkLimit() && this.checkLower())) {
throw new Error("input 양식 중 user값에 오류가 발생하였습니다.");
}
}
}