객체 지향 프로그래밍 패러다임이 등장하기 전 절차 지향 프로그래밍이 있었다. 이전에는 모든것을 절차적으로 생각해왔으며 기껏해야 함수로 이동하는것이 전부였다. 초기의 C, 포트란 같은 언어들은 객체 지향의 개념이 없는 절차적 언어였다. 객체지향 프로그램이 패러다임이 등장하며 단순히 별개의 변수와 함수로 순차적 작동하는 것을 넘어, 데이터의 접근과 데이터의 처리 과정에 대한 모형을 만들어내는 방법을 고안해냈다. 따라서, 데이터와 기능이 별개로 취급되지 않고, 한번에 묶여서 처리할 수 있게 되었다.
자바스크립트는 엄밀히 말해 객체 지향 언어는 아니지만, 객체 지향 패턴으로 작성할 수 있다.객체 지향 언어 "클래스"라고 부르는 데이터 모델의 청사진을 사용해 코드 작성 현대의 언어들은 대부분 객체 지향의 특징을 갖고 있음 (대표적으로 Java, C++, C# 등) JavaScript: 객체 지향으로 작성 가능하다!
객체 지향 언어
"클래스"라고 부르는 데이터 모델의 청사진을 사용해 코드 작성
현대의 언어들은 대부분 객체 지향의 특징을 갖고 있음 (대표적으로 Java, C++, C# 등)
JavaScript: 객체 지향으로 작성 가능
객체 지향 프로그래밍
객체 지향 프로그래밍(Object-Oriented Programming, OOP)은컴퓨터 프로그래밍의패러다임중 하나이다.
OOP Basic Concepts
OOP는 프로그램 설계 철학 개념이다
OOP의 모든 것은 "객체"로 그룹화된다.
OOP의 4가지 주요 개념(Encapsulation (캡슐화), Inheritance (상속), Abstraction (추상화), Polymorphism (다형성))을 통해 재사용성을 얻을 수 있다.
캡슐화
데이터(속성)와 기능(메서드)을 따로 정의하는 것이 아닌, 하나의 객체 안에 넣어서 묶는 것
캡슐화라는 개념은 "은닉화"의 특징도 포함하고 있는데, 은닉화는 내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것.
은닉(hiding): 구현은 숨기고, 동작은 노출시킴
느슨한 결합(Loose Coupling)에 유리: 언제든 구현을 수정할 수 있음
JavaScript의 캡슐화는 개체의 구현 세부 정보를 숨기고 개체와 상호 작용할 수 있는 공용 인터페이스만 노출하는 방법을 나타낸다.
// 예제) 은행 계좌에 대한 클래스를 고려
class BankAccount {
constructor(balance) {
this._balance = balance;
}
deposit(amount) {
this._balance += amount;
}
withdraw(amount) {
if (this._balance >= amount) {
this._balance -= amount;
} else {
console.log("Insufficient funds");
}
}
get balance() {
return this._balance;
}
}
/*
_balance클래스에는 계정의 현재 잔액을 저장 하는 전용 변수 가 있습니다.
이 클래스에는 계정과 상호 작용하는 데 사용되는 공용 메서드 deposit, withdraw, 가 있습니다.
get balance클래스의 사용자는 잔액을 확인하고 거래를 할 수 있지만 내부 잔액을 보거나 변경할 수는 없습니다.
이렇게 하면 개체의 내부 상태( _balance이 경우 속성)가 보호되고 제공된 메서드를 통해서만 수정할 수 있으므로
개체가 일관된 상태로 유지되고 변경 시 필요한 논리가 실행되도록 합니다.
*/
추상화
추상화는 프로그래밍에서 구체적인 구현 내용을 숨기고, 기능을 제공하는 인터페이스만 노출하는 것을 의미한다.
자바스크립트에서는 클래스를 사용해 추상화를 구현할 수 있다. 예를 들어, 사용자는 구체적인 구현 내용을 몰라도 클래스에서 제공하는 메소드를 사용할 수 있다.
예를 들어, 우리는 객체지향 프로그래밍에서 기본적인 개념인 "상속"을 사용해 계층적 구조를 구성할 수 있다.(메소드를 사용하면서 구체적인 구현 내용을 몰라도 된다.)
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
speak() {
console.log(`${this.name} barks.`);
}
}
class Cat extends Animal {
constructor(name) {
super(name);
}
speak() {
console.log(`${this.name} meows.`);
}
}
const dog = new Dog('Fido');
const cat = new Cat('Whiskers');
dog.speak(); // Fido barks.
cat.speak(); // Whiskers meows.
/*
예제에서, Animal 클래스는 공통적인 기능(speak)을 가지며 Dog와 Cat 클래스는 이를 상속받아 구체적인 구현을 하고 있다.
이렇게 함으로써, 사용자는 Animal 클래스에서 제공하는 speak() 메소드를 사용하면서 구체적인 구현 내용을 몰라도 된다.
이러한 개념이 추상화 개념이다.
*/
상속(inheritance)과 프로토타입(prototype)
상속은 부모 클래스의 특징을 자식 클래스가 물려받는 것
상속을 받은 새로운 클래스가 기존의 클래스의 자료와 연산을 이용할 수 있게 하는 기능이다.
상속을 받는 새로운 클래스를하위 클래스,자식 클래스라고 하며 새로운 클래스가 상속하는 기존의 클래스를상위 클래스,부모 클래스라고 한다.
상속을 통해서 기존의 클래스를 상속받은 하위 클래스를 이용해 프로그램의 요구에 맞추어 클래스를 수정할 수 있고 클래스 간의 종속 관계를 형성함으로써 객체를 조직화할 수 있다.
// 상속 예시
// ES5
function Person() {
this.name = "annonymous";
this.sayHello = function() {
alert("Hello, my name is" + this.name);
}
}
function Yoda() {
var obj = new Person();
obj.name = "Yoda";
return obj;
}
var me = new Yoda();
me.sayHello();
console.log(me instanceof Yoda); // false
console.log(me instanceof Person); // true
//ES6
class Person {
constructor() {
this.name = "annonymous";
}
sayHello() {
console.log(Hello, my name is ${this.name});
}
}
class Yoda extends Person {
constructor() {
super();
this.name = "Yoda";
}
}
const me = new Yoda();
me.sayHello();
console.log(me instanceof Yoda); // true
console.log(me instanceof Person); // true
자바스크립트의 객체는 명세서에서 명명한 [[Prototype]]이라는 숨김 프로퍼티를 갖는다. 이 숨김 프로퍼티 값은 null이거나 다른 객체에 대한 참조가 되는데, 다른 객체를 참조하는 경우 참조 대상을 '프로토타입(prototype)'이라 부른다.
프로토타입의 동작 방식
object에서 프로퍼티를 읽으려고 하는데 해당 프로퍼티가 없으면 자바스크립트는 자동으로 프로토타입에서 프로퍼티를 찾는다. 이런 동작 방식을 '프로토타입 상속’이라 부른다. [[Prototype]] 프로퍼티는 내부 프로퍼티이면서 숨김 프로퍼티이지만 다양한 방법을 사용해 개발자가 값을 설정할 수 있다.
다형성(Polymorphism)
poly는 "많은", 그리고 morph는 "형태"라는 뜻을 가지고 있다. 합쳐서 Polymorphism이라는 단어. 즉 "다양한 형태"라는 뜻.
똑같은 메서드라 하더라도, 다른 방식으로 구현될 수 있다
ex) 부모 클래스의 '고양이'에 울음 속성이 있다. 고양이 클래스를 상속받은 '사자'가 있다고 하면 사자에게도 울음 속성이 자동으로 상속된다. 앞서 이것은 상속이라 설명했다. 그런데 고양이 과의 사자는 울음소리가 다를것이다. 같은 울음 속성이라도 실제로는 다르다.이러한 경우를 자바스크립트에서 재정의 하여 사용할 수 있다.
부모 클래스로부터 상속을 받은 속성에 대해, 자식 클래스에서 물려받은 속성을 재정의 할 수 있습니다. 이것을오버라이딩이라고 한다.
다향성이 없었다면 기본(부모) 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 할 것이다.
다향성이 있음으로 같은 이름의 속성을 유지함으로서, 속성을 사용하기 위한 인터페이스를 유지하고, 메서드 이름을 낭비하지 않는다.