만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다.
whoAmI
와talk
메소드를 가진People
객체 만들기
1. 오리 타입의 객체를 인자로 받음
2. 객체의 `걷기` 메소드와 `꽥꽥거리기` 메소드를 차례로 호출하는 함수를 만듬
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public interface People {
String whoAmI = "People";
void talk();
}
public static class Human implements People {
String whoAmI = "Human";
public void talk() {
System.out.println(whoAmI);
}
}
public static class Robot {
String whoAmI = "robot";
public void talk() {
System.out.println(whoAmI);
}
}
public static void startTalk(Human human){
human.talk();
}
public static void main (String[] args) throws java.lang.Exception
{
Human human = new Human();
Robot robot = new Robot();
startTalk(human);
startTalk(robot); // 에러 발생(error: incompatible types)
}
}
위의 코드는 여기 에서 볼 수 있다.
1. 객체에 `whoAmI`와 `talk` 메소드를 만듬
2. 만약 `whoAmI`와 `talk` 메소드를 호출할 시점에 객체에 두 메소드가 없다면 런타임 에러가 발생
- 즉, 객체가 `걷기` 메소드나 `꽥꽥거리기` 메소들르 가지고 있다면 `People` 객체로 간주하겠다는 암시가 깔려있음
// typescript 로 만든 예시
interface People {
talk(): void;
whoAmI: string;
}
class Human implements People {
whoAmI = "human"
talk = () => {
console.log(`say ${this.whoAmI} : 말할 수 있어요`);
}
}
class Robot {
whoAmI = "robot"
talk = () => {
console.log(`say ${this.whoAmI} : 말할 수 있어요`);
}
}
const humanInstance = new Human();
const robotInstance = new Robot();
function startTalk(people: People): void {
people.talk();
}
startTalk(humanInstance); // --- 1) "say human : 말할 수 있어요"
startTalk(robotInstance); // --- 2) "say robot : 말할 수 있어요"
startTalk(robotInstance)
에서 분명히 에러가 날 것 같지만 typescript의 duck typing으로 인해 에러가 나지 않는다.(위의 코드는 Typesrcipt playground 에서도 확인 가능하다!)
타입스크립트는
다형성
보통 객체 지향 언어에서 밑처럼 부른다.
class People:
whoAmI = 'people'
def talk(self):
print(f'say {People.whoAmI} : 말할 수 있어요')
class Human:
whoAmI = 'human'
def talk(self):
print(f'say {Human.whoAmI} : 말할 수 있어요')
class Robot:
whoAmI = 'robot'
def chat(self):
print(f'say {Robot.whoAmI} : 채팅할 수 있어요')
def startTalk(entity):
entity.talk()
people = People()
human = Human()
robot = Robot()
startTalk(people)
startTalk(human)
startTalk(robot) # Throws the error `'robot' object has no attribute 'talk'`
talk()
메소드가 있는 것만으로 호출하는 startTalk(entity)
함수에서 talk()
가 정상적으로 실행된다.talk()
메소드가 없기 떄문에, AttributeError
가 발생한다.단위 테스트
와 같은 테스트가 굉장히 중요하다.