덕 타이핑
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
덕 타이핑은 객체의 실제 타입보다는 객체가 가진 메서드와 속성을 기준으로 적합성을 판단하는 프로그래밍 방식으로, "오리처럼 보이고, 오리처럼 운다면 오리다"라는 비유에서 유래되었다. 파이썬, 루비, C++, C#, VB.NET 등 다양한 프로그래밍 언어에서 구현되며, 템플릿, 동적 타입, 리플렉션 등을 활용하여 덕 타이핑과 유사한 기능을 제공한다. 덕 타이핑은 유연성을 제공하지만, 런타임 오류 가능성을 높이고 코드 가독성을 저해할 수 있다는 비판도 존재한다.
더 읽어볼만한 페이지
- 유형 이론 - 형 변환
형 변환은 프로그래밍에서 변수의 데이터 타입을 변경하는 것으로, 암시적 형 변환과 명시적 형 변환으로 나뉘며, 객체 지향 프로그래밍에서는 업캐스팅과 다운캐스팅이 발생하고, 각 언어는 고유한 규칙과 방법을 제공하며 잘못된 형 변환은 오류를 유발할 수 있다. - 유형 이론 - 대수적 자료형
대수적 자료형은 합 타입과 곱 타입을 조합하여 새로운 자료형을 정의하는 방법으로, 단일 연결 리스트나 이진 트리와 같은 자료 구조를 표현하고 패턴 매칭을 통해 자료형의 구조를 분해 및 처리하는 데 유용하며, 함수형 프로그래밍 언어에서 널리 사용된다. - 객체 지향 프로그래밍 - Is-a
Is-a 관계는 객체 지향 프로그래밍에서 한 유형이 다른 유형의 하위 유형임을 나타내는 관계로, 상속, 서브타이핑, 리스코프 치환 원칙과 관련되며, C++, Python, Java 등에서 표현된다. - 객체 지향 프로그래밍 - 객체 (컴퓨터 과학)
객체는 객체 지향 프로그래밍에서 데이터와 조작을 묶어 메시지를 수신하고, 프로그램의 개념을 표현하며 가시성과 재사용성을 높이는 실체이다. - 빈 문단이 포함된 문서 - 광주고등법원
광주고등법원은 1952년에 설치되어 광주광역시, 전라남도, 전북특별자치도, 제주특별자치도를 관할하며, 제주와 전주에 원외재판부를 두고 있다. - 빈 문단이 포함된 문서 - 1502년
1502년은 율리우스력으로 수요일에 시작하는 평년으로, 이사벨 1세의 이슬람교 금지 칙령 발표, 콜럼버스의 중앙아메리카 해안 탐험, 바스쿠 다 가마의 인도 상관 설립, 크리미아 칸국의 킵차크 칸국 멸망, 비텐베르크 대학교 설립, 최초의 아프리카 노예들의 신대륙 도착 등의 주요 사건이 있었다.
덕 타이핑 | |
---|---|
개요 | |
범주 | 객체 지향 프로그래밍 |
타이핑 | 동적 타이핑 |
설명 | |
정의 | 어떤 객체의 변수나 메소드에 접근할 때, 객체의 타입을 확인하는 대신 실제 그 변수와 메소드가 존재하는지 확인하는 방식의 프로그래밍 |
특징 | 특정 타입에 얽매이지 않고, 필요한 메소드나 속성만 있다면 객체를 사용할 수 있다. 코드의 유연성과 재사용성을 높일 수 있다. |
비유 | 만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를 것이다. |
장단점 | |
장점 | 코드의 간결성 증가 유연성 향상 코드 재사용성 증가 |
단점 | 실행 시간에 타입 오류 발생 가능성 증가 디버깅의 어려움 코드의 가독성 저하 가능성 |
적용 | |
주요 사용 언어 | 파이썬 루비 스몰토크 자바스크립트 펄 PHP Objective-C Swift C++ (템플릿 사용 시) C# (dynamic 타입 사용 시) |
2. 역사
덕 타이핑이라는 용어는 "덕 테스트" 비유에서 비롯되었다.[1]
덕 타이핑의 핵심은 객체의 실제 타입보다 객체가 어떤 메서드와 속성을 가지고 있느냐에 따라 그 적합성을 판단하는 것이다.
정적 타입 언어는 컴파일 시점에 타입 검사를 수행하는 반면, 동적 타입 언어는 런타임에 타입 검사를 수행한다.[12] 동적 타입에서는 객체 (변수의 값)가 무엇을 할 수 있는지 (어떤 인터페이스를 가지고 있는지)는 런타임 시 객체 자체가 결정한다.
:"만약 그것이 오리처럼 걷고, 오리처럼 꽥꽥거린다면, 그것은 틀림없이 오리일 것이다."
데이브 토마스가 루비 커뮤니티에서 처음 이 말을 사용한 것으로 알려져 있다.[1]
3. 개념적 예제
다음은 덕 타이핑을 사용하는 의사코드 예제이다.
```
function calculate(a, b, c) => return (a+b)*c
a = calculate (1, 2, 3)
b = calculate ([1, 2, 3], [4, 5, 6], 2)
c = calculate ('apples ', 'and oranges, ', 3)
print to_string a
print to_string b
print to_string c
```
위 코드의 실행 결과는 다음과 같다.
```
9
[1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6]
apples and oranges, apples and oranges, apples and oranges,
```
다음은 파이썬 코드 예제이다.
```python
class Duck:
def swim(self):
print("오리 수영")
def fly(self):
print("오리 비행")
class Whale:
def swim(self):
print("고래 수영")
for animal in [Duck(), Whale()]:
animal.swim()
animal.fly()
```
위 코드의 출력은 다음과 같다.
```
오리 수영
오리 비행
고래 수영
AttributeError: 'Whale' object has no attribute 'fly'
```
이 예제에서 `Whale` 클래스는 `swim` 메서드는 가지고 있지만 `fly` 메서드는 가지고 있지 않다. 따라서 `animal.fly()`를 호출했을 때 `AttributeError`가 발생한다. 만약 수영할 수 있는 모든 것이 오리라고 가정할 수 있다면, 고래도 오리로 간주될 수 있다. 그러나 오리가 날 수 있어야 한다는 가정이 추가되면 고래는 오리로 간주되지 않는다.
다음은 파이썬과 C++ 코드 예제이다.
```python
class Duck:
def quack(self):
print("꽥꽥!")
def feathers(self):
print("오리에게 흰색, 회색 깃털이 있습니다.")
class Person:
def quack(self):
print("이 사람이 오리를 흉내내네요.")
def feathers(self):
print("사람은 바닥에서 깃털을 주워서 보여 줍니다.")
def in_the_forest(duck):
duck.quack()
duck.feathers()
def game():
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
```
```c++
class Duck {
public:
void quack() {
std::cout << "Quaaaaaack!" << std::endl;
}
void feathers() {
std::cout << "The duck has white and gray feathers." << std::endl;
}
}
class Person {
public:
void quack() {
std::cout << "The person imitates a duck." << std::endl;
}
void feathers() {
std::cout << "The person takes a feather from the ground and shows it." << std::endl;
}
}
template
void inTheForest(T& t)
{
t.quack();
t.feathers();
}
int main()
{
Duck donald;
Person jhon;
inTheForest( donald );
inTheForest( jhon );
}
```
위 두 예제에서 `in_the_forest` 함수(또는 `inTheForest` 함수)는 `Duck` 타입의 객체뿐만 아니라 `quack`과 `feathers` 메서드를 가진 모든 객체를 인자로 받을 수 있다. 이것이 덕 타이핑의 핵심 개념을 보여주는 예시이다.
4. 다른 형 체계와의 비교
덕 타이핑은 상속을 통한 서브 타입 (부분형) 다형성 (subtype polymorphism영어)[13]을 주로 사용하는 정적 타입의 객체 지향 언어인 Java나 C#에서, 객체가 특정 인터페이스의 모든 메서드를 가지고 있다면, 해당 클래스가 해당 인터페이스를 선언적으로 구현하지 않더라도, 객체는 런타임에 해당 인터페이스를 구현하는 것으로 간주할 수 있다는 개념이다. 이는 또한, 같은 인터페이스를 구현하는 객체끼리, 각각이 어떤 상속 계층을 가지고 있는지와 관계없이 서로 교환 가능하다는 의미이기도 하다.
이 용어의 이름은 "덕 테스트"에서 유래했다.
> "만약 그것이 오리처럼 걷고, 오리처럼 꽥꽥거린다면, 그것은 틀림없이 오리일 것이다."
C++의 템플릿은 덕 타이핑의 정적 버전이다. 예를 들어, STL의 다양한 iterator는 Iterator 기본 클래스에서 메서드를 상속받는 것은 아니지만, 특정 연산자를 사용할 수 있고 같은 구문으로 컴파일이 통과되면 iterator의 일종으로 취급된다. "같은 인터페이스를 갖는다"는 것은 컴파일러에게 시그니처와 같은 인터페이스가 같다는 것을 의미한다. 따라서 iterator 구현은 객체일 필요도 없다.
OCaml의 구조적 서브타이핑 (structural subtyping영어)은 덕 타이핑과 유사한 접근 방식이다. 메서드 시그니처가 호환된다면, 선언적인 상속 관계가 없더라도, 객체 타입은 호환된다. 이것은 OCaml의 타입 추론 시스템에 의해 컴파일 시점에 결정된다(컴파일러에 의한 정적 타입 검사). TypeScript의 타입 호환성 역시 구조적 서브타이핑을 기반으로 한다.[18] 이와 대립되는 개념은 명목적 서브타이핑 (nominal subtyping영어)이며, Java나 C# 등 상속 기반 타입 시스템에서 사용된다.
Python과 Ruby는 일반적인 클래스 상속 기능도 가지고 있으며, 상속에 의한 다형성도 사용할 수 있지만, 덕 타이핑에 의한 다형성은 상속이 필요 없으며, 타입에 의한 제약에 얽매이지 않고 간단한 코드로 구현할 수 있다는 장점이 있다. 그러나 제약이 없다는 것은 남용하기 쉽다는 의미이기도 하다. 타입 제약이 없는 경우 컴파일러에 의한 정적 타입 검사나 통합 개발 환경 (IDE)에 의한 코드 완성 등의 지원을 기대할 수 없으며, 프로그램의 기술 오류를 발견하기 어려울 수도 있다. Python의 덕 타이핑에서는 객체가 특정 속성을 실제로 가지고 있는지 `hasattr()`로 사전 검사하거나, 예외 처리를 기술하는 방법이 채택된다.[11] Python은 덕 타이핑을 보완하기 위해 추상 기본 클래스 기능을 도입했다.[19]
4. 1. 구조적 타입 시스템
덕 타이핑은 구조적 타이핑과 유사하지만 구별된다. 구조적 타이핑은 타입의 구조에 따라 타입 호환성 및 동등성을 결정하는 정적 타이핑 시스템인 반면, 덕 타이핑은 동적이며 런타임 중에 액세스되는 타입 구조의 해당 부분에 의해서만 타입 호환성을 결정한다.[6][7][8]
정적 타입 언어는 컴파일 시점에 타입 검사를 수행하는 반면, 동적 타입 언어는 런타임에 타입 검사를 수행한다.[12] 즉, 동적 타입에서는 객체(변수의 값)가 무엇을 할 수 있는지(어떤 인터페이스를 가지고 있는지)는 런타임 시 객체 자체가 결정한다.
덕 타이핑에 대해, 상속 기능을 통한 서브 타입 (부분형) 다형성 (subtype polymorphism영어)[13]을 주로 사용하는 정적 타입의 객체 지향 언어인 Java나 C#의 개념으로 예시를 들면, 객체가 특정 인터페이스의 모든 메서드를 가지고 있다면, 해당 클래스가 해당 인터페이스를 선언적으로 구현하지 않더라도, 객체는 런타임에 해당 인터페이스를 구현하는 것으로 간주할 수 있다는 것이다. 이는 또한, 같은 인터페이스를 구현하는 객체끼리, 각각이 어떤 상속 계층을 가지고 있는지와 관계없이 서로 교환 가능하다는 의미이기도 하다. 덕 타이핑은 구조적 타이핑 (structural typing영어)과 유사하며, 구조적 타이핑의 다형성은 row polymorphism|로우 다형성영어[14] (행 다형[15] 또는 열 다형[16]이라고도 한다)으로 분류될 수 있다. 구조적 타이핑은 명목적 타이핑 (nominal typing / nominative typing영어)[17]과 대비되는 타입 시스템의 분류 중 하나이다.
4. 2. 프로토콜과 인터페이스
스몰토크에서는 동일한 프로토콜(protocol)을 구현하는 클래스들은 보통 동일한 상속 계층에 속하나, 꼭 그럴 필요는 없다. 프로토콜과 인터페이스는 일부 메서드, 연산자 또는 동작이 정의되어야 함을 명시적으로 선언하는 방법을 제공한다.
덕 타이핑을 사용하면 어댑터 패턴 없이 객체를 직접 사용할 수 있다. 정적 타입 언어는 컴파일 시점에 타입 검사를 수행하는 반면, 동적 타입 언어는 런타임에 타입 검사를 수행한다.[12] 즉, 동적 타입에서는 객체가 무엇을 할 수 있는지(어떤 인터페이스를 가지고 있는지)는 런타임 시 객체 자체가 결정한다.
덕 타이핑은 상속을 통한 서브 타입 (부분형) 다형성(subtype polymorphism)[13]을 주로 사용하는 정적 타입의 객체 지향 언어인 Java나 C#에서, 객체가 특정 인터페이스의 모든 메서드를 가지고 있다면, 해당 클래스가 해당 인터페이스를 선언적으로 구현하지 않더라도, 객체는 런타임에 해당 인터페이스를 구현하는 것으로 간주할 수 있다는 개념이다. 이는 또한, 같은 인터페이스를 구현하는 객체끼리, 각각이 어떤 상속 계층을 가지고 있는지와 관계없이 서로 교환 가능하다는 의미이기도 하다.
4. 3. 템플릿 또는 제네릭 타입
템플릿 (또는 제네릭) 함수나 메서드는 정적 타입 환경에서 덕 타이핑과 유사한 유연성을 제공하지만, 런타임이 아닌 컴파일 타임에 타입이 결정된다. 이는 정적 타입 검사와 동적 타입 검사의 장단점을 모두 가진다. 덕 타이핑은 런타임에 실제로 호출되는 메서드만 구현하면 되므로 더 유연할 수 있지만, 템플릿은 컴파일 시간에 도달 불가능함을 증명할 수 없는 모든 메서드의 구현을 필요로 한다.[9]
C++의 템플릿은 덕 타이핑의 정적 버전이다. 예를 들어, STL의 다양한 iterator는 Iterator 기본 클래스에서 메서드를 상속받는 것은 아니지만, 특정 연산자를 사용할 수 있고 같은 구문으로 컴파일이 통과되면 iterator의 일종으로 취급된다. 여기서 "같은 인터페이스를 갖는다"는 것은 컴파일러에게 시그니처와 같은 인터페이스가 같다는 것을 의미한다. 따라서 iterator 구현은 객체일 필요도 없다.
다음은 C++에서 템플릿을 사용한 덕 타이핑 예시이다.
```cpp
#include
template
void test(const T& t) {
std::cout << t.sound() << std::endl;
}
struct Duck {
const char* sound() const {
return "quack";
}
};
struct Cat {
const char* sound() const {
return "myaa";
}
};
int main() {
test(Duck());
test(Cat());
}
```
이 코드에서 `test` 함수는 템플릿을 사용하여 `sound()` 메서드를 가진 모든 타입을 받을 수 있다. `Duck`과 `Cat` 구조체는 각각 `sound()` 메서드를 정의하고 있으므로, `test` 함수에서 덕 타이핑이 적용된다. 템플릿에 의한 덕 타이핑은 컴파일 시점에 해결되는 정적 다형성이며, 실행 시 오버헤드가 없다.
5. 구현
파이썬은 덕 타이핑을 적극적으로 활용하는 대표적인 동적 타입 언어이다. 파이썬에서는 객체가 특정 속성을 실제로 가지고 있는지 `hasattr()`로 사전 검사하거나, 예외 처리를 기술하는 방법이 채택된다.[11]
class Duck:
def swim(self):
print("오리 수영")
def fly(self):
print("오리 비행")
class Whale:
def swim(self):
print("고래 수영")
for animal in [Duck(), Whale()]:
animal.swim()
animal.fly()
출력:
오리 수영
오리 비행
고래 수영
AttributeError: 'Whale' object has no attribute 'fly'
위 예시에서 `Duck` 클래스와 `Whale` 클래스는 `swim` 메서드를 가지고 있다. `for` 루프는 `Duck` 객체와 `Whale` 객체에 대해 `swim` 메서드를 호출한다. `Whale` 클래스는 `fly` 메서드가 없기 때문에 `AttributeError` 예외가 발생한다.
파이썬은 덕 타이핑을 보완하기 위해 추상 기본 클래스 기능을 도입했다.[19]
Ruby에서도 덕 타이핑을 지원한다.
def test(foo)
puts foo.sound
end
class Duck
def sound
'quack'
end
end
class Cat
def sound
'myaa'
end
end
test(Duck.new)
test(Cat.new)
출력 결과:
```text
quack
myaa
```
두 클래스는 상속 관계가 없다. 위의 `test` 메서드는 `sound`라는 이름을 가진 멤버가 있는 객체라면 무엇이든 받아들인다. Ruby의 `puts`는 인자 객체를 자동으로 문자열로 변환하여 표준 출력으로 출력하므로, 문자열 이외의 값을 반환하는 `sound`라도 받아들인다. 이러한 유연성이 동적 언어의 특징이다.[11]
C++의 템플릿은 덕 타이핑의 정적 버전이다.[12]
```cpp
#include
template
void test(const T& t) {
std::cout << t.sound() << std::endl;
}
struct Duck {
const char* sound() const {
return "quack";
}
};
struct Cat {
const char* sound() const {
return "myaa";
}
};
int main() {
test(Duck());
test(Cat());
}
```
위 코드는 덕 타이핑을 C++ 템플릿으로 구현한 예시다. `test` 함수는 템플릿으로 정의되어 `sound()` 메서드를 가진 모든 타입을 인자로 받을 수 있다. 실행 결과는 템플릿에 의한 덕 타이핑이 컴파일 시점에 해결되는 정적 다형성이며, 동적 타입 언어와는 달리 실행 시 오버헤드를 수반하지 않는다.
C#은 버전 4.0부터 `dynamic` 형을 사용하여 동적 타입 지정을 지원한다. `dynamic`은 내부적으로 리플렉션을 이용하며, 메서드나 속성의 존재 여부를 실행 시간에 평가한다. 심볼 해결에 실패하면 예외가 발생한다.[21]
```csharp
using System;
class Duck {
public string Sound() {
return "꽥꽥";
}
}
class Cat {
public string Sound() {
return "야옹";
}
}
public class DuckTypingTest {
static void Test(dynamic obj) {
Console.WriteLine(obj.Sound());
}
public static void Main() {
Test(new Duck());
Test(new Cat());
}
}
```
C#은 C++의 템플릿과 유사한 제네릭을 지원하지만, C++ 템플릿만큼 유연하지 않아 덕 타이핑에는 사용할 수 없다.[22]
Visual Basic .NET(VB.NET)은 `Option Strict Off` 설정을 통해 지연 바인딩(late binding)을 지원하며, 이를 통해 덕 타이핑을 구현할 수 있다.[23][24]
```vb.net
Option Strict Off ' 지연 바인딩을 허용한다.
'Option Strict On ' 지연 바인딩을 허용하지 않는다.
Imports System
Class Duck
Public Function Sound() As String
Return "꽥꽥"
End Function
End Class
Class Cat
Public Function Sound() As String
Return "야옹"
End Function
End Class
Public Class DuckTypingTest
Shared Sub Test(obj As Object)
Console.WriteLine(obj.Sound())
End Sub
Public Shared Sub Main()
Test(new Duck())
Test(new Cat())
End Sub
End Class
```
Java는 언어 구문 수준에서 동적 타이핑을 지원하지 않지만, 리플렉션을 사용하면 덕 타이핑과 유사한 기능을 구현할 수 있다. Core Reflection API로, `java.lang.reflect` 패키지가 제공된다.[25] COM에서도, `IDispatch` 인터페이스[26]를 구현함으로써 덕 타이핑과 유사한 기능을 구현할 수 있다.
5. 1. 파이썬
파이썬은 덕 타이핑을 적극적으로 활용하는 대표적인 동적 타입 언어이다. 파이썬 튜토리얼의 용어 항목은 덕 타이핑을 다음과 같이 설명하고 있다.[11]
파이썬에서는 객체가 특정 속성을 실제로 가지고 있는지 `hasattr()`로 사전 검사하거나, 예외 처리를 기술하는 방법이 채택된다.[11]
다음은 덕 타이핑을 활용한 파이썬 코드 예시이다.
class Duck:
def swim(self):
print("오리 수영")
def fly(self):
print("오리 비행")
class Whale:
def swim(self):
print("고래 수영")
for animal in [Duck(), Whale()]:
animal.swim()
animal.fly()
출력:
오리 수영
오리 비행
고래 수영
AttributeError: 'Whale' object has no attribute 'fly'
위 예시에서 `Duck` 클래스와 `Whale` 클래스는 `swim` 메서드를 가지고 있다. `for` 루프는 `Duck` 객체와 `Whale` 객체에 대해 `swim` 메서드를 호출한다. `Whale` 클래스는 `fly` 메서드가 없기 때문에 `AttributeError` 예외가 발생한다. 만약 수영할 수 있는 모든 것이 오리라고 가정할 수 있다면, 고래도 오리로 간주될 수 있다. 그러나 오리가 날 수 있어야 한다는 가정이 추가되면 고래는 오리로 간주되지 않는다.
파이썬은 덕 타이핑을 보완하기 위해 추상 기본 클래스 기능을 도입했다.[19]
5. 2. Ruby
ruby
def test(foo)
puts foo.sound
end
class Duck
def sound
'quack'
end
end
class Cat
def sound
'myaa'
end
end
test(Duck.new)
test(Cat.new)
```
출력 결과:
```text
quack
myaa
```
두 클래스는 상속 관계가 없다. 위의 `test` 메서드는 `sound`라는 이름을 가진 멤버가 있는 객체라면 무엇이든 받아들인다. Ruby의 `puts`는 인자 객체를 자동으로 문자열로 변환하여 표준 출력으로 출력하므로, 문자열 이외의 값을 반환하는 `sound`라도 받아들인다. 이러한 유연성이 동적 언어의 특징이다.[11]
5. 3. C++
C++의 템플릿은 덕 타이핑의 정적 버전이다. 예를 들어, STL에서의 다양한 iterator는 Iterator 기본 클래스와 같은 것에서 메서드를 상속받는 것은 아니지만, 특정 연산자를 사용할 수 있고 같은 구문으로 컴파일이 통과된다면, 그것은 iterator의 일종으로 취급될 수 있다.[12] 이 맥락에서 "같은 인터페이스를 갖는다"는 것은 컴파일러에게 시그니처와 같은 인터페이스가 같다는 것이다. 따라서, iterator의 구현은 객체일 필요조차 없다.
```cpp
#include
template
void test(const T& t) {
std::cout << t.sound() << std::endl;
}
struct Duck {
const char* sound() const {
return "quack";
}
};
struct Cat {
const char* sound() const {
return "myaa";
}
};
int main() {
test(Duck());
test(Cat());
}
```
위 코드는 덕 타이핑을 C++ 템플릿으로 구현한 예시다. `test` 함수는 템플릿으로 정의되어 `sound()` 메서드를 가진 모든 타입을 인자로 받을 수 있다. `Duck`과 `Cat` 구조체는 `sound()` 메서드를 가지고 있으므로, `test` 함수에 사용될 수 있다. 실행 결과는 템플릿에 의한 덕 타이핑이 컴파일 시점에 해결되는 정적 다형성이며, 동적 타입 언어와는 달리 실행 시 오버헤드를 수반하지 않는다.
5. 4. C#
C#은 버전 4.0부터 `dynamic` 형을 사용하여 동적 타입 지정을 지원한다. `dynamic`은 내부적으로 리플렉션을 이용하며, 메서드나 속성의 존재 여부를 실행 시간에 평가한다. 심볼 해결에 실패하면 예외가 발생한다.[21]
```csharp
using System;
class Duck {
public string Sound() {
return "꽥꽥";
}
}
class Cat {
public string Sound() {
return "야옹";
}
}
public class DuckTypingTest {
static void Test(dynamic obj) {
Console.WriteLine(obj.Sound());
}
public static void Main() {
Test(new Duck());
Test(new Cat());
}
}
```
C#은 C++의 템플릿과 유사한 제네릭을 지원하지만, C++ 템플릿만큼 유연하지 않아 덕 타이핑에는 사용할 수 없다.[22]
5. 5. VB.NET
Visual Basic .NET(VB.NET)은 `Option Strict Off` 설정을 통해 지연 바인딩(late binding)을 지원하며, 이를 통해 덕 타이핑을 구현할 수 있다.[23][24] 이는 VB.NET이 초기에 Visual Basic 및 Visual Basic for Applications(VBA)에서 코드를 쉽게 이전할 수 있도록 느슨한 형식 지정을 지원했기 때문이다.
다음은 `Option Strict Off`를 설정하여 덕 타이핑을 사용하는 VB.NET 코드 예시이다. `Option Strict On`으로 설정하면 정적 형식 검사가 활성화되어 컴파일 오류가 발생한다.
```vb.net
Option Strict Off ' 지연 바인딩을 허용한다.
'Option Strict On ' 지연 바인딩을 허용하지 않는다.
Imports System
Class Duck
Public Function Sound() As String
Return "꽥꽥"
End Function
End Class
Class Cat
Public Function Sound() As String
Return "야옹"
End Function
End Class
Public Class DuckTypingTest
Shared Sub Test(obj As Object)
Console.WriteLine(obj.Sound())
End Sub
Public Shared Sub Main()
Test(new Duck())
Test(new Cat())
End Sub
End Class
5. 6. 기타 언어 (Java, COM)
Java는 언어 구문 수준에서 동적 타이핑을 지원하지 않지만, 리플렉션을 사용하면 덕 타이핑과 유사한 기능을 구현할 수 있다. Core Reflection API로, `java.lang.reflect` 패키지가 제공된다.[25] 또한, JNI를 사용하면 C 언어나 C++ 등의 네이티브 코드에서 Java로 작성된 클래스를 사용할 수 있으며, 리플렉션과 마찬가지로 덕 타이핑에 응용할 수도 있다.
COM에서도, `IDispatch` 인터페이스[26]를 구현함으로써 덕 타이핑과 유사한 기능을 구현할 수 있다. VBScript나 JScript와 같은 스크립트 언어(동적 프로그래밍 언어)의 구현을 용이하게 하기 위한 기반으로, 확장 인터페이스 `IDispatchEx`도 제공된다.[27]
6. 비판
덕 타이핑은 코드 구현을 간결하게 할 수 있다는 장점이 있지만, 남용될 위험도 있다. 타입 제약이 없으면 통합 개발 환경(IDE)의 코드 완성 지원이나 컴파일러의 정적 타입 검사를 받기 어려워 프로그램 오류를 발견하기 힘들 수 있다.[11] 이러한 문제점을 보완하고자 Python은 `hasattr()`를 이용한 사전 검사, 예외 처리, 추상 기본 클래스 기능 등을 덕 타이핑과 함께 활용한다.[11][19]
참조
[1]
웹사이트
Glossary — Python 3.7.1 documentation
https://docs.python.[...]
2018-11-08
[2]
웹사이트
Python Duck Typing - Example
https://techiehours.[...]
2020-07-26
[3]
webarchive
Boo: Duck Typing
http://boo.codehaus.[...]
2008-10-06
[4]
웹사이트
Dynamic classes and duck typing
https://forum.dlang.[...]
[5]
웹사이트
Metaprogramming - duck typing in D
https://stackoverflo[...]
[6]
웹사이트
SE Radio Episode 384: Boris Cherny on TypeScript
https://www.se-radio[...]
2019-10-25
[7]
웹사이트
Core Language · An Introduction to Elm
http://guide.elm-lan[...]
2017-01-30
[8]
웹사이트
PEP 544 – Protocols: Structural subtyping (static duck typing)
https://peps.python.[...]
[9]
웹사이트
StackOverflow: Implement duck typing using java MethodHandles
https://stackoverflo[...]
2020-06-13
[10]
웹사이트
Python Duck Typing - Example
https://techiehours.[...]
2020-07-26
[11]
웹사이트
Glossary — Python 3.7.1 documentation, §duck-typing
https://docs.python.[...]
2018-11-08
[12]
Oracle
Dynamic typing vs. static typing
https://docs.oracle.[...]
[13]
서적
型システム入門 −プログラミング言語と型の理論−
オーム社
2013-03-26
[14]
문서
Objects and Aspects: Row Polymorphism
https://www.cs.cmu.e[...]
Neel Krishnaswami, Department of Computer Science, Carnegie Mellon University
[15]
문서
実例によるPureScript
https://aratama.gith[...]
[16]
문서
OCamlで構築するモダンWeb:型付きHTML5プログラミングの実際
http://proofcafe.org[...]
有限会社ITプランニング | 今井 敬吾
[17]
서적
型システム入門 −プログラミング言語と型の理論−
オーム社
2013-03-26
[18]
문서
TypeScript: Documentation - Type Compatibility
https://www.typescri[...]
[19]
웹사이트
Glossary — Python 3.10.1 documentation, §abstract base class
https://docs.python.[...]
2021-12-19
[20]
문서
Kernel.#puts (Ruby 3.0.0 リファレンスマニュアル)
https://docs.ruby-la[...]
[21]
문서
dynamic 型の使用 - C# プログラミング ガイド | Microsoft Docs
https://docs.microso[...]
[22]
문서
Differences Between C++ Templates and C# Generics - C# Programming Guide | Microsoft Docs
https://docs.microso[...]
[23]
문서
Object Variable Declaration - Visual Basic | Microsoft Docs
https://docs.microso[...]
[24]
문서
Early and Late Binding - Visual Basic | Microsoft Docs
https://docs.microso[...]
[25]
문서
Java Core Reflection
https://docs.oracle.[...]
[26]
문서
IDispatch Interface and Accessibility - Windows applications | Microsoft Docs
https://docs.microso[...]
[27]
문서
IDispatchEx Interface | Microsoft Docs
https://docs.microso[...]
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com