10.1 다형성의 기초
다형성은 객체지향 프로그래밍(OOP)의 주요 개념 중 하나야. 일반적으로 다형성은 다양한 클래스의 객체가 동일한 인터페이스를 사용하여 데이터를 처리할 수 있게 해줘. JavaScript 컨텍스트에서, 이는 서로 다른 객체들이 같은 이름의 메소드를 가질 수 있고, 구체적인 타입에 대한 지식 없이 그 메소드들이 호출될 수 있다는 것을 의미해.
다형성의 유형
JavaScript에서 주요 다형성 유형은 다음과 같아:
1. Ad-hoc 다형성:
- 메소드의 다형성, 다른 타입의 객체에 대해 동일한 이름의 메소드 호출
- 예시로는 함수 및 연산자 오버로딩이 포함되어 있는데, 이는 JavaScript에서 직접 지원되지는 않지만 시뮬레이션할 수 있어
2. 서브타입 다형성 (Subtype polymorphism):
- 서브타입 또는 포함 다형성, 같은 기본 클래스를 상속하는 서로 다른 클래스의 객체들이 기본 클래스의 객체로 처리될 수 있을 때
- 이것은 상속과 인터페이스를 통해 구현된 주요 다형성 유형이야
다형성의 장점:
- 코드 단순화: 다형성은 더 유연하고 일반적인 코드를 작성할 수 있게 해주며, 이는 객체의 구체적인 타입을 알지 않고도 다양한 객체 타입과 함께 작동할 수 있어.
- 확장성: 다형성은 기존 코드를 변경하지 않고도 시스템에 새로운 타입과 동작을 추가하기 쉽게 만들어줘.
- 지원: 다형성은 책임의 분리를 돕고 코드의 가독성 및 유지 관리를 향상시켜.
10.2 JavaScript에서 다형성의 예
상속을 통한 서브타입 다형성
예제 1: 동일한 인터페이스를 통해 다양한 객체 타입 처리
이 예제에서 함수 playWithAnimal
은 Animal
타입의 객체를 받고, 메소드 makeSound
를 호출해. Dog
와 Cat
객체들이 Animal
을 상속받아 makeSound
메소드를 재정의하고, 각 객체에서 메소드를 호출할 때마다 다른 결과를 만들어내.
class Animal {
makeSound() {
console.log('어떤 일반적인 소리');
}
}
class Dog extends Animal {
makeSound() {
console.log('멍멍!');
}
}
class Cat extends Animal {
makeSound() {
console.log('야옹!');
}
}
function playWithAnimal(animal) {
animal.makeSound();
}
const dog = new Dog();
const cat = new Cat();
playWithAnimal(dog); // 출력: 멍멍!
playWithAnimal(cat); // 출력: 야옹!
10.3 인터페이스를 통한 다형성 (Duck Typing)
JavaScript에는 TypeScript나 Java 같은 다른 언어처럼 인터페이스에 대한 내장 지원이 없어. 대신 "덕 타이핑" (Duck Typing)이라는 접근 방식을 사용해. 이는 객체가 특정 타입이나 상속과 관계없이 필요한 메소드와 속성을 가지고 있다면 인터페이스에 부합한다고 보는 거야.
덕의 법칙: 어떤 것이 오리처럼 보이고, 오리처럼 헤엄치고, 오리처럼 꽥꽥거린다면, 그것은 아마도 오리일 것이다.
예제 2: 덕 타이핑 사용
이 예제에서 함수 takeOff
는 fly
메소드를 가진 아무 객체나 받아들여. Bird
와 Airplane
객체들은 fly
메소드를 구현하여, takeOff
로 전달될 수 있어.
class Bird {
fly() {
console.log('날고 있어...');
}
}
class Airplane {
fly() {
console.log('제트 엔진 소리가...');
}
}
function takeOff(flyingObject) {
flyingObject.fly();
}
const bird = new Bird();
const airplane = new Airplane();
takeOff(bird); // 출력: 날고 있어...
takeOff(airplane); // 출력: 제트 엔진 소리가...
10.4 함수에 의한 다형성
JavaScript에서는 함수가 일급 객체이며, 다형적 행동을 구현하기 위해 전달되고 사용할 수 있어.
예제 3: 함수에 의한 다형성
이 예제에서 함수 greet
는 다른 함수를 인수로 받아 호출해. 이는 다양한 기능을 수행할 수 있는 여러 가지 함수를 사용할 수 있게 해줘.
function greetMorning() {
console.log('좋은 아침이에요!');
}
function greetEvening() {
console.log('좋은 저녁이에요!');
}
function greet(greetingFunction) {
greetingFunction();
}
greet(greetMorning); // 출력: 좋은 아침이에요!
greet(greetEvening); // 출력: 좋은 저녁이에요!
10.5 메소드 오버로딩에 의한 다형성 (시뮬레이션)
JavaScript는 다른 프로그래밍 언어처럼 메소드 오버로딩을 직접 지원하지 않아. 하지만 함수 인수와 타입 체크를 사용하여 메소드 오버로딩을 시뮬레이션할 수 있어.
예제 4: 메소드 오버로딩 시뮬레이션
이 예제에서 add
메소드는 두 개의 인수를 받고, 인수의 타입에 따라 다양한 행동을 수행해. 만약 인수가 숫자라면, 메소드는 이를 더해. 만약 인수가 배열이라면, 메소드는 이를 병합해.
class Calculator {
add(a, b) {
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (Array.isArray(a) && Array.isArray(b)) {
return a.concat(b);
} else {
throw new Error('잘못된 인수');
}
}
}
const calc = new Calculator();
console.log(calc.add(1, 2)); // 출력: 3
console.log(calc.add([1, 2], [3, 4])); // 출력: [1, 2, 3, 4]
GO TO FULL VERSION