메서드 호출은 객체.메서드()
와 같이 객체 내에 메서드를 호출하는 방법을 의미
단순 객체를 사용한 이러한 예제를 흔히 볼 수 있습니다. 다음은 카운터를 구현한 예제
// counter 예시
let counter1 = {
value: 0,
increase: function() {
this.value++ // 메서드 호출을 할 경우, this는 counter1을 가리킵니다
},
decrease: function() {
this.value--
},
getValue: function() {
return this.value
}
}
counter1.increase()
counter1.increase()
counter1.increase()
counter1.decrease()
counter1.getValue() // 2
counter1
은 단 하나의 객체만 만들 수 있습니다. 똑같은 기능을 하는 카운터를 여러 개 만드는 방법 중 하나는, 아래 예제 코드와 같이 클로저 모듈 패턴을 이용할 수 있습니다.
// 클로저 모듈 패턴으로 구현한 counter 예시
function makeCounter() {
let value = 0;
return {
increase: function() {
value++;
},
decrease: function() {
value--;
},
getValue: function() {
return value;
}
}
}
let counter1 = makeCounter()
counter1.increase()
counter1.getValue() // 1
let counter2 = makeCounter()
counter2.decrease()
counter2.decrease()
counter2.getValue() // -2
클래스와 생성자 함수의 차이
new 연산자
없이 호출하면 에러가 발생한다. new 연산자
없이 호출하면 일반 함수로서 호출된다.extends
와 super
키워드를 제공한다. extends
와 super
키워드를 지원하지 않는다.strict mode
가 지정되어 실행되며 strict mode
를 해제할 수 없다. strict mode
가 지정되지 않는다.let avante = new Car ('hyndai', 'avante', 'black');
let mini = new Car ('bmw', 'mini', 'white');
let beetle = new Car ('volkswagen', 'beetles', 'red');
Car
라는 클래스의 고유한 속상과, 메소드를 갖습니다.function Car (brand, name, color) {
// 인스턴스가 만들어질 때 실행되는 코드
}
class Car {
constructor (brand, name, color) {
// 인스턴스가 만들어질 때 실행되는 코드
}
}
Object Oriented Programming
)Encapsulation
)하나의 객체 안에 넣어서 묶는 것.
느슨한 결합
: 코드 실행 순서에 따라 절차적으로 코드를 작성하는 것이 아니라, 코드가 상징하는 실제 모습과 닮게 코드를 모아 결합하는 것을 의미.은닉화
내부 데이터나 내부 구현이 외부로 노출되지 않도록 만드는 것.
Abstraction
)
캡슐화
가 코드나 데이터의 은닉에 포커스가 맞춰져있다면,
추상화
는 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 단순한 이름으로 정의하는 것에 포커스가 맞춰져 있다.
✅ 클래스 정의 시, 메서드와 속성만 정의한 것을 인터페이스라고 부릅니다. 이것이 추상화의 본질
Inheritance
)기본 클래스(base class)의 특징을 파생 클래스(derived class)가 상속받는다
사람(Human)
이라는 클래스가 있다고 가정해 봅시다.학생(Student)
이라는 클래스를 작성한다고 생각해 봅시다.사람(Human)
클래스의 속성과 메서드를 다시 구현한다면 비효율적일 것이다.학생(Student)
클래스는 사람(Human)
클래스를 상속받을 수 있다.Polymorphism
)Textarea
(TextBox), Select
, 그리고 Checkbox
등 HTML에서는 이와 같이 모든 요소를 전부 Element라고 부른다.render
라는 이름을 갖고 있다고 가정해보자.TextBox
, Select
, Checkbox
의 공통의 부모인 HTML Element
라는 클래스에 render
라는 메서드를 만들고 상속을 받게 만들 수 있습니다.TextBox
는 가로로 긴 네모 상자와 커서가 있는 형태일 것이고, Select
박스는 눌렀을 때 선택지가 나오도록 화면에 그려야 할 것이다.다형성 (
Polymorphism
)이 없다면?
- 기본(부모) 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 할 것이다.
- 또는 각각의 자식 클래스에 별도의 각기 다른
render
함수를 만들 수도 있겠지만, 엘리먼트라는 클래스의 본질상 "화면에 뿌린다"(render)는 개념은 부모가 갖고 있는 것이 합리적이다.
주요 개념 | 장점 |
---|---|
캡슐화 | 코드가 복잡하지 않게 만들고, 재사용성을 높인다. |
추상화 | 코드가 복잡하지 않게 만들고, 단순화된 사용으로 변화에 대한 영향을 최소화한다. |
상속 | 불필요한 코드를 줄여 재사용성을 높인다. |
다형성 | 동일한 메서드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해진다. |
private
키워드)의 한계private
이라는 키워드를 제공.TypeScript의 예제로, name
이라는 속성이 존재한다. 그러나 private
키워드가 붙어 있어서, 클래스 내부에서만 사용 가능하다.
// TypeScript 문법입니다.
class Animal {
private name: string;
constructor(theName: string) {
this.name = theName;
}
}
new Animal("Cat").name; // 사용 불가
// Property 'name' is private and only accessible within class 'Animal'.
#
이라는 키워드가 도입interface
키워드) 기능의 부재객체 지향 프로그래밍의 주요 키워드 중 하나인 추상화는, 속성과 메서드의 이름만 노출시켜서 사용을 단순화한다는 의미를 갖고 있다.
즉, 인터페이스(interface)의 단순화를 의미합니다. Java나 TypeScript 언어는 언어의 주요 기능으로 interface를 구현해 놓았다.
// TypeScript 문법입니다.
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {}
}
인터페이스의 이점은, 인터페이스가 일종의 규약처럼 간주되어, 인터페이스를 클래스로 구현하는 사람들이 이에 맞게 작성할 수 있게 돕는다.
이는 클래스를 이용하는 입장에서 노출된 인터페이스를 통해 "이 클래스는 메서드 이름이 의도한 바대로 작동할 것이다"
라는 것을 명백히 드러나게 해 줍니다.
또한 실질적인 구현 방법을 공개하지 않고, 사용법을 노출시키기에도 유리합니다.