본문 바로가기
IT 공부/객체지향 설계 공부

동적 타입 언어와 정적 타입 언어의 차이점 (덕 타이핑)

by exdus3156 2023. 12. 13.

0. 서론: 객체와 타입

객체지향에서 객체를 구현하는 주요 문법은 클래스다. 클래스는 많은 오해가 있다. 대표적인 예시가 바로 클래스를 붕어빵을 만드는 틀로 묘사하는 것이다.

 

붕어빵틀 비유는 클래스라는 문법 장치를 객체의 구현 코드로 인식하기 때문에 발생하는 오해다. 그러나 클래스는 객체를 구현하기 위한 코드가 아니라, 객체의 타입(type)을 구현하기 위한 코드다.

객체의 타입과 클래스 문법에 대한 자세한 설명은 <객체지향의 사실과 오해> 책에서 잘 기술되어 있다. (링크

여기서 간단히 요약하자면, 객체의 타입(type)이란 객체(object)를 분류(classify)하기 위한 추상화/일반화된 개념(concept)이며, 클래스 문법은 바로 이 개념, 즉 타입(type)을 구현하는 코드라는 것이다. 특정 클래스로 분류될 수 있는 객체를 해당 클래스의 인스턴스(instance)라고 부른다.

객체지향에서 객체의 타입은 오직 행동으로 분류된다. 바로 이 지점에서 데이터 타입(Data type)과 구분된다. 데이터 타입이 데이터와 그것을 다루는 연산을 제공해주는 반면, 객체의 타입은 객체를 분류해주는 장치이며 내부의 데이터와 메소드를 캡슐화해서 숨겨버린다.

 

1. 자바와 자바스크립트의 타입 분류 방식

자바는 대표적인 정적 타입 언어이고, 자바스크립트는 대표적인 동적 타입 언어다.

정적(static)과 동적(dynamic) 타입 언어는 객체의 타입이 코드 상에서 명시적으로 분류되어야 하는지 여부에 따라 갈린다. 정적 타입은 코드, 즉 컴파일 단계에서 미리 명시적으로 확실하게 분류되어야 한다. 동적 타입은 코드로 일일이 타입을 작성하지 않아도 된다. 런타임 단계에서 인터프리터와 같은 머신이 해석해준다.

이렇게 언어의 타입 체계가 정적인지 동적인지에 따라 소스 코드가 완전히 달라진다. 

자바는 대표적인 정적 타입 언어다. 소스코드 상에서 인스턴스가 어떤 타입(클래스)인지 명시적으로 드러내야만 하며, 드러내지 않으면 컴파일 오류에서 벗어날 수 없다. 

이것은 자바가 객체지향 언어라는 사실을 고려하면 사실 생각해 볼만 하다. 객체지향에서 객체의 타입은 오직 행동으로만 식별되고 분류될 수 있다. 따라서 같은 행동을 한다면 같은 타입으로 생각해도 된다. 아니 그래야만 한다.

하지만 자바는 정적 타입 언어다! 따라서 자바는 어떤 타입으로 분류되려면 반드시 소스 코드 상에서 특정 타입이라고 스스로를 증명해야 한다.

즉 달리 말하면, 같은 public interface를 가져서 같은 행동을 하는 객체라고 해도! 같은 타입이라고 자바 개발자가 소스 코드로 명시하지 않는 이상, 같은 타입이 아닌 것이다.

자바의 객체는 부모 클래스, 추상 클래스나 인터페이스를 상속해서 반드시 같은 타입으로 분류될 수 있음을, 즉 같은 행동을 이미 하고 있음에도 불구하고 코드로 드러내야 한다. 

이런 면에서는 자바스크립트와 같은 동적 타입 언어가 조금 더 객체지향의 원칙에 가까운 모습을 보여준다. (그렇다고 자바스크립트다 우월하다는 뜻은 아님) 자바스크립트는 함수의 인자로 전달된 객체가 어떤 타입인지 따지지 않는다. 실제로 소스코드 상에서 어떤 타입인지도 모른 채, 즉시 해당 객체에게 어떤 메소드를 호출해버린다.

따라서 런타입에 해당 메소드를 실행할 수만 있다면 그 어떤 타입의 객체가 온다고 하더라도 실행 가능하다. 객체의 행동만 일치한다면 무조건 받아들이는 것이다. 자바스크립트의 이러한 모습은 사실상 자바의 인터페이스의 기능을 코드로 작성하지도 않고 바로 사용해버리는 것과 비슷하다.

자바스크립트는 완전히 메시지에만 의존한다. 

 

2. 덕 타이핑

덕 타이핑(Duck Typing)은 프로그래밍에서 객체의 유형이나 클래스보다는 객체의 메서드나 속성의 존재로 객체의 적합성을 판단하는 프로그래밍 스타일을 말합니다. "덕 타이핑"이라는 용어는 "만약 오리처럼 걷고, 소리치고, 헤엄치면 그것은 오리다"라는 말에서 파생되었습니다. 즉, 어떤 객체가 특정한 인터페이스의 메서드나 속성을 지원한다면, 해당 객체는 해당 인터페이스를 따른다고 간주되는 것입니다.

chatGPT에서 덕 타이핑에 대해 검색하니 위와 같이 나왔다! 

여하튼, 덕 타이핑이란 사실상 동적 타입 언어에서 지원되는 기능으로서, 자바에서는 제공되지 않는 것으로 알고 있다.

굳이 따지자면 자바는 인터페이스나 추상클래스를 통해 객체가 메시지에 의존할 수 있도록 강제한다. 그러나 이것은 덕 타이핑이 아니다. 덕 타이핑이란 오리처럼 행동하면 오리라고 볼 수 있어야 한다. 자바는 오리처럼 행동할 수 있어도 "나는 오리다"라고 스스로 말해야만 오리로 취급받으므로 덕 타이핑은 아니다.

자바스크립트를 쓰다 보면 자바에 비해 굉장히 유연하고 편하다는 인상을 받게 되는데, 사실 인상이 아니라 정말로 유연하다. 타입 체계에서 그 차이가 나타난다.

굳이 따지자면, 객체의 타입이 오직 객체의 행동으로만 분류된다는 점에서 봤을 때 자바는 약간 아쉬움이 있다. 행동으로만 분류한다고는 하지만 사실상 행동이 아니라 인터페이스나 추상클래스 상속을 통해 자신이 어떤 타입인지 코드 상에서 증명 시키도록 강제하기 때문이다.

하지만 정적 타입 언어는 그 대신 컴파일 타임에서 오류를 컴파일 단계에서 강력하게 검증할 수 있다. 오류를 찾아내는 디버깅은 굉장히 중요하기 때문에 자바스크립트 개발자조차 타입스크립트를 배울 정도다.

어떤 언어든 한 쪽이 우월한 것이 아니라 다 장단점이 있는 것이다.