프로그래밍언어론 15강 - 추상 자료형, 객체와 다형성
제어 추상화와 자료 추상화에서 출발해 캡슐화·정보 은닉·추상 자료형의 원리를 학습한다. 객체와 클래스, 생성자와 소멸자, VTab을 이용한 늦은 바인딩을 이해하고 경험적·매개변수적·서브타입 다형성과 인터페이스·트레잇의 관계를 정리한다.
제1장 추상화와 추상 자료형
1. 추상화의 의미와 방법
추상화(abstraction)는 복잡한 대상을 필요한 수준에서 간략하게 나타내는 것이다. 관심 있는 부분만 골라 나타내는 추리기와 관심 없는 부분을 제거하는 삭제하기라는 두 관점으로 설명할 수 있다. 추상화는 대상을 왜 사용하는지에 맞추어 중요한 성질을 드러내고 불필요한 세부를 감춘다.
예를 들어 성적 처리 프로그램에서 학생을 나타낼 때 학번, 이름, 수강 과목, 성적은 중요하지만 그 밖의 모든 개인 정보를 표현할 필요는 없다. 추상화는 현실의 대상을 그대로 복제하는 것이 아니라 현재 문제 해결에 필요한 관점으로 재구성한다.
2. 제어 추상화와 자료 추상화
제어 추상화는 복잡한 제어 과정을 단순한 이름과 인터페이스로 제공한다. 제어 구조와 서브프로그램이 이를 지원하며 초기 프로그래밍 언어가 특히 중시했다. sort(list, len)을 호출할 때 사용자는 정렬 알고리즘의 세부 절차인 ‘어떻게’를 일일이 작성하지 않고 목록을 정렬한다는 ‘무엇’을 표현한다.
자료 추상화는 복잡한 자료 구조를 단순한 개념으로 제공한다. 자료 구조와 추상 자료형이 이를 지원한다. 스택을 사용할 때 원소 저장 공간과 스택 포인터의 구체적인 관리 방식 대신 push, pop, isEmpty 같은 연산으로 다룬다. 제어 추상화가 발달하고 자료 구조에 연산을 적용하면서 자료와 연산을 한 묶음으로 다루는 추상 자료형이 발전했다.
| 구분 | 숨기는 복잡성 | 대표 지원 |
|---|---|---|
| 제어 추상화 | 처리를 수행하는 구체적인 제어 과정 | 제어 구조, 서브프로그램 |
| 자료 추상화 | 데이터의 구체적인 표현과 저장 구조 | 자료 구조, 추상 자료형 |
3. 캡슐화와 정보 은닉
캡슐화(encapsulation)는 여러 요소를 하나의 단위로 묶는 기능이다. C의 구조체는 서로 다른 필드를 하나의 자료 단위로 묶고, 공용체와 함수도 관련 요소를 구성 단위로 조직하는 데 사용된다. 캡슐화의 초점은 흩어진 요소를 응집된 하나의 단위로 다루는 데 있다.
정보 은닉(information hiding)은 구현 세부 사항을 감추고 외부에 인터페이스만 공개하는 기능이다. C의 파일 범위 식별자와 C++ 클래스의 private·protected 멤버가 예이다. 외부 코드는 공개된 public 연산을 통해서만 내부 상태를 사용한다.
두 용어는 같은 의미로 사용되기도 하지만 관점을 구분할 수 있다. 캡슐화는 요소를 묶는 구조에, 정보 은닉은 묶음 안의 구현을 외부에서 보지 못하게 하는 접근 통제에 무게를 둔다. 둘을 함께 사용하면 구현에 종속된 코드 사용을 막고 한 부분의 변경이 예상치 못한 곳까지 연속적인 변경을 부르는 파급 효과(ripple effect)를 줄일 수 있다.
핵심: 공개 인터페이스가 유지되면 내부 표현과 구현을 바꾸더라도 이용하는 쪽의 코드를 변경하지 않을 수 있다. 이것이 추상 자료형의 수정 용이성과 정보 은닉의 중요한 효과이다.
4. 추상 자료형
추상 자료형(ADT, Abstract Data Type)은 자료 집합과 그 자료에 적용 가능한 연산을 함께 선언한 자료형이다. 구현 세부 사항은 캡슐화를 통해 외부에 공개하지 않으며, 해당 타입의 자료를 사용하려면 외부에 공개된 인터페이스를 이용해야 한다.
큐를 예로 들면 ENQ, DEQ, ISEMPTY는 외부에 공개할 수 있는 연산이다. 원소를 어느 배열에 저장하고 앞뒤 인덱스를 어떻게 관리하는지는 표현부에 숨긴다. 구현 내부에는 외부 인터페이스에 포함되지 않는 보조 연산이 있을 수도 있지만, 사용자는 공개된 연산만으로 큐를 다룬다.
추상 자료형은 세 가지 장점을 제공한다. 첫째, 사용하는 부분을 바꾸지 않고 구현 코드를 교체할 수 있어 수정이 쉽다. 둘째, 같은 추상 자료형을 여러 상황에서 재사용할 수 있다. 셋째, 구현 세부를 프로그램의 다른 부분에서 임의로 바꾸지 못하게 해 보안성과 무결성을 높인다.
5. 자료 표현이 없는 추상 자료형과 대수적 자료형
추상화 수준을 최대한 높이면 자료 표현 없이 연산만 정의하는 추상 자료형을 만들 수 있다. Java의 인터페이스가 예이다. 스택이라면 내부 배열이나 포인터를 제시하지 않고 연산 사이에 만족해야 할 법칙을 정의한다. isEmpty(makeStack()) == true, isEmpty(push(s,e)) == false, pop(push(s,e)) == e는 스택 연산의 의미적 관계를 보여 준다.
대수적 자료형은 타입 자체에 적용하는 대수적 연산으로 새로운 타입을 만든다. 데카르트곱이 대표 예이다. 수학의 집합 A×B처럼 컴퓨터에서는 자료형 T1과 T2를 결합해 쌍 자료형 (T1,T2)를 구성할 수 있다.
제2장 객체와 클래스
1. 객체지향 개념의 출발
객체지향 개념은 시뮬레이션 분야에서 발전했다. 객체는 실세계의 구체적인 대상을 프로그램에 필요한 관점으로 추상화한 것이다. 초기 GUI가 책상 위의 문서와 도구를 모형화한 것처럼, 사용자가 익숙한 대상을 상태와 동작으로 나타낸다. 객체는 자료와 연산을 함께 묶기 때문에 추상 자료형을 구현하는 데 매우 효과적이다.
2. 객체의 상태와 행태
객체는 특정 상태를 유지하면서 외부 요청에 반응하는 행태를 보이는 대상이다. 상태는 필요에 따라 달라질 수 있다. 속성은 객체의 상태를 정의하는 값이고, 필드는 속성을 저장하는 이름이다. 메소드는 객체에 대한 요청을 처리하는 서브프로그램이며, 메시지는 요청 구문 전체를 객체에 전달하는 것이다.
예를 들어 스택 객체의 배열, 최대 길이, 현재 꼭대기 위치는 상태를 구성하는 필드이고, push, pop, isempty는 메시지에 반응하는 메소드이다. 외부 사용자는 공개 메소드로 상태 변화를 요청한다.
3. 클래스와 인스턴스
클래스는 같은 메소드 집합과 필드 항목을 공유하는 객체의 묶음이자 객체 생성의 틀이다. 클래스를 통해 실제로 생성된 객체를 그 클래스의 인스턴스라고 한다. 메타클래스는 모든 클래스의 클래스 구실을 하는 객체이다.
정적 타입을 지원하는 객체지향 언어에서는 클래스가 타입이 되고 객체는 그 타입의 원소가 된다. 필드와 메소드의 개수나 이름은 수행 중 바뀌지 않는다. 동적 타입 객체지향 언어에서는 필드와 메소드의 개수나 이름이 수행 중 바뀔 수 있다. 오리 타입(duck typing)은 선언된 클래스 이름보다 객체가 실제로 지원하는 메소드에 따라 타입을 판단하는 시스템이다.
클래스는 객체 하나가 아니라 공통 구조와 동작을 정의한 틀이다. 인스턴스마다 필드 값이라는 상태는 달라질 수 있지만 같은 클래스의 메소드 집합과 필드 항목을 공유한다.
4. 생성자와 소멸자
생성자는 객체 생성에 사용되는 특별한 메소드이다. 일반 메소드처럼 직접 호출하기보다 new 연산자나 객체 변수 선언 같은 방법에 의해 자동으로 호출된다. 필드를 여러 방식으로 초기화할 수 있도록 서로 다른 인수 조합으로 중복 정의할 수 있다.
소멸자는 객체가 소멸할 때 호출되는 특별한 메소드이다. delete 연산자나 영역 탈출 등에 의해 자동으로 호출되며 중복 정의되지 않는다. 소멸자를 지원하지 않는 언어는 더 이상 사용하지 않는 객체의 메모리를 회수하기 위해 쓰레기 수집기(garbage collector)를 사용한다.
5. C++와 Java의 스택 클래스
C++ 스택 클래스는 정수 배열을 가리키는 stack_ptr, 최대 인덱스 max_len, 현재 꼭대기 top_ptr를 전용 필드로 둔다. 생성자는 크기를 받아 new int[size]로 배열을 만들고 꼭대기를 -1로 초기화한다. 소멸자 ~stack()은 delete[] stack_ptr로 동적 배열을 해제한다.
push는 스택이 가득 찼는지 검사한 뒤 꼭대기 인덱스를 증가시키고 값을 저장한다. pop은 비었는지 검사하고 꼭대기를 감소시키면서 마지막 값을 반환한다. isempty는 꼭대기가 -1인지 확인한다. 내부 표현은 private이고 외부에는 연산 메소드가 공개된다.
Java 예제도 정수 배열 참조, 최대 인덱스, 꼭대기 인덱스를 전용 필드로 두고 생성자와 push·pop·isempty를 공개한다. Java에서는 C++의 소멸자와 수동 배열 해제 대신 쓰레기 수집 환경을 사용한다. 두 예는 문법과 메모리 관리 방식은 다르지만 같은 스택 추상 자료형을 클래스로 구현한다.
제3장 늦은 바인딩과 객체지향 구현
1. 수신 객체에 따른 메소드 선택
객체지향의 핵심은 같은 메소드 호출이 수신 객체에 따라 다르게 동작할 수 있다는 점이다. 호출 전에 어떤 객체가 메시지를 받을지 고정할 수 없다면 실제 수행 시점에 객체에 맞는 메소드 구현을 선택해야 한다. 이를 위해 호출 메소드의 늦은 바인딩이 필요하다.
2. 가상함수 테이블
늦은 바인딩은 보통 가상함수 테이블(VTab)을 이용해 구현한다. VTab은 객체와 연관된 메소드의 코드 주소를 담는 테이블이다. 메소드가 호출되면 수신 객체와 연결된 VTab에서 해당 항목의 주소를 찾고 그 주소의 함수를 호출한다. 따라서 동일한 호출 구문이라도 객체가 연결한 테이블 항목에 따라 다른 구현을 실행할 수 있다.
C++에서는 virtual 키워드가 붙은 멤버 함수만 늦은 바인딩의 대상이 된다. 늦은 바인딩은 다형성을 구현하는 한 가지 방법이며, 모든 이름 중복이나 모든 함수 호출이 자동으로 늦은 바인딩되는 것은 아니다.
실행 흐름: 메소드 이름 호출 → 수신 객체 확인 → 객체와 연관된 VTab 항목 조회 → 저장된 코드 주소의 함수 실행. 이 과정이 수신 객체별 동작 차이를 가능하게 한다.
제4장 다형성의 종류
1. 다형성과 두 지원 수준
다형성(polymorphism)은 여러 타입의 데이터를 같은 이름으로 처리할 수 있는 특성이다. 여러 타입을 다룰 수 있는 서브프로그램을 다형 서브프로그램이라고 하고, 타입을 인수로 받는 타입을 다형 타입이라고 한다.
서브프로그램의 다형성은 경험적 다형성, 매개변수적 다형성, 서브타입 다형성으로 나뉜다. 강의에서는 서브타입 다형성을 순수 다형성이라고도 부른다. 세 종류는 같은 이름으로 여러 타입을 다룬다는 결과는 비슷하지만 실제 구현을 선택하는 기준이 다르다.
2. 경험적 다형성
경험적 다형성(ad-hoc polymorphism)은 실제로는 서로 다른 서브프로그램에 같은 이름을 붙인 형태이다. 사용자 정의 서브프로그램의 중복 정의(overloading)가 대표적이며 C++, Java, Ada 등 많은 객체지향 언어가 지원한다. 호출할 때 인수의 개수와 타입을 이용해 어느 구현을 선택할지 결정한다.
연산자 중복 정의도 경험적 다형성이다. 같은 +라는 기호라도 정수 피연산자에는 정수 덧셈을, 실수 피연산자에는 실수 덧셈을 적용한다. C++와 Python에서는 사용자가 연산자 동작을 타입에 맞게 정의할 수도 있다.
중복 정의와 기본 인수는 충돌할 수 있다. void f(double b=0.0);과 void f();가 함께 있을 때 f()를 호출하면 두 선언이 모두 후보가 될 수 있다. 중복 정의된 함수나 연산자의 실제 구현을 결정하는 시그니처 매칭 알고리즘이 하나를 확정하지 못하면 오류가 발생한다. 반환 타입만 다른 int g(int)와 double g(int)도 같은 인수 시그니처만으로 호출 대상을 구분할 수 없다.
3. 매개변수적 다형성
매개변수적 다형성(parametric polymorphism)은 타입을 매개변수로 전달받는 형태이다. 타입 인수는 명시적으로 전달하거나 문맥에서 암시적으로 정할 수 있다. Ada는 generic 패키지, C++은 템플릿, Java는 제너릭으로 이를 지원한다.
C++의 template <typename Type> void generic_sort(Type list[], int len)은 정렬할 원소 타입을 매개변수 Type으로 받는 틀이다. generic_sort<int>와 generic_sort<double>처럼 구체적인 타입 인수를 주어 정수 목록과 실수 목록에 같은 알고리즘 이름을 사용한다.
강의에 따르면 Ada와 C++의 범용 서브프로그램은 틀 구실을 하며 실제 컴파일 시간에 구체적인 타입마다 코드를 개별적으로 복사한다. 경험적 다형성이 서로 다른 구현에 같은 이름을 붙이는 것이라면, 매개변수적 다형성은 하나의 일반화된 틀에 타입을 인수로 전달한다.
4. 순수 다형성과 상속
순수 다형성(pure polymorphism) 또는 서브타입 다형성(subtype polymorphism)은 클래스의 상속 관계, 즉 IS-A 관계에 의해 결정된다. 서브클래스가 부모 클래스의 한 종류라는 의미를 만족하는 상속을 적합 상속이라고 한다. 부모 타입의 자리에 서브타입 객체를 사용하고 실제 객체에 맞는 메소드가 선택될 수 있다.
추상 클래스는 직접 객체를 만들 수 없을 정도로 극도로 추상화된 클래스이다. 공통 규약과 일부 구현을 상속 계층에 제공한다. 구상 클래스는 실제로 객체를 생성할 수 있는 클래스이다.
| 다형성 | 구현 선택 기준 | 대표 수단 |
|---|---|---|
| 경험적 다형성 | 인수 개수와 타입에 맞는 별도 구현 | 함수·연산자 중복 정의 |
| 매개변수적 다형성 | 전달된 타입 인수 | Ada generic, C++ template, Java generic |
| 서브타입 다형성 | IS-A 상속 관계와 실제 수신 객체 | 상속, 가상 메소드와 늦은 바인딩 |
제5장 상속, 인터페이스와 트레잇
1. 단일 상속과 다중 상속
단일 상속은 하나의 부모 클래스로부터 상속하는 경우이고, 다중 상속은 여러 부모 클래스로부터 상속하는 경우이다. C++은 다중 상속을 지원한다. 여러 부모의 기능을 결합할 수 있지만 공통 조상에서 내려온 같은 필드나 메소드가 여러 경로로 전달되면 참조가 모호해질 수 있다.
2. 다이아몬드 상속 문제
다이아몬드 상속 문제는 다중 상속으로 인해 서브클래스에서 필드나 메소드를 어느 경로의 것으로 참조해야 하는지 모호해지는 문제이다. 예를 들어 Student와 Teacher가 모두 Human을 상속하고 TA가 두 클래스를 모두 상속하면 Human 부분이 두 경로로 들어올 수 있다.
C++에서는 공통 부모를 가상 클래스로 지정하는 가상 상속으로 해결한다. 공통 기반 클래스의 인스턴스를 하나로 공유하게 하여 중복과 참조 모호성을 줄인다.
3. 인터페이스
인터페이스(interface)는 추상 메소드 집합으로만 구성된 타입이며 구체적인 메소드 구현은 구상 클래스가 제공한다. Java에서 Speakable 인터페이스가 speak를 선언하면 Human 클래스는 이를 구현해 실제 출력 동작을 작성한다.
인터페이스는 추상 클래스와 비슷하지만 차이가 있다. 추상 클래스는 클래스 상속 계층 안에서 공통 기반을 제공하는 데 활용되며, 인터페이스는 특정 클래스 계층과 독립적으로 존재하면서 서로 다른 클래스가 같은 규약을 구현하게 할 수 있다.
4. 트레잇
트레잇(trait)은 인터페이스와 비슷하지만 일부 메소드를 구현해 둘 수 있다. Java 8 이후의 인터페이스는 트레잇의 특성을 반영했고, PHP와 Rust도 트레잇을 지원한다. Ruby에서는 믹스인(mixin), Haskell에서는 클래스라는 이름으로 유사 개념을 지원한다.
트레잇은 일반적으로 상속하거나 구현한다고 표현하기보다 사용(use)한다고 말한다. PHP 예제에서 Hello 트레잇은 sayHello 메소드 구현을 가지고, Human 클래스가 use Hello로 그 구현을 사용한다. 클래스 계층을 새로 만들지 않고 공통 동작을 여러 클래스에 제공할 수 있다.
비교: 추상 클래스는 상속 계층의 기반, 인터페이스는 계층과 독립적인 추상 메소드 규약, 트레잇은 재사용할 수 있는 일부 메소드 구현까지 포함할 수 있는 구성 단위이다.
핵심 개념 정리
추상화는 복잡한 대상에서 필요한 부분을 추리고 불필요한 세부를 감춘다. 제어 추상화는 수행 과정, 자료 추상화는 데이터 표현을 단순화한다. 추상 자료형은 자료 집합과 연산을 함께 선언하고 구현을 숨긴 채 공개 인터페이스로만 사용하게 한다.
객체는 상태를 유지하며 메시지에 메소드로 반응하고, 클래스는 공통 필드와 메소드를 갖는 객체 생성의 틀이다. 생성자는 객체를 초기화하고 소멸자는 소멸 시 자원을 정리한다. 수신 객체별 메소드 선택은 VTab을 통한 늦은 바인딩으로 구현할 수 있다.
다형성은 여러 타입을 같은 이름으로 처리하는 성질이다. 경험적 다형성은 중복 정의, 매개변수적 다형성은 타입 인수, 서브타입 다형성은 IS-A 상속 관계를 이용한다. 다중 상속은 다이아몬드 문제를 만들 수 있으며, 인터페이스와 트레잇은 클래스 계층을 보완해 규약과 구현을 재사용한다.
최종 정리: ‘무엇을 공개하고 무엇을 숨기는가’, ‘어떤 기준으로 실제 메소드 구현을 선택하는가’를 중심으로 개념을 연결해야 한다. ADT의 인터페이스, 객체의 상태와 메소드, 늦은 바인딩, 세 가지 다형성, 추상 클래스·인터페이스·트레잇의 차이가 핵심이다.
예상문제 20선
1. 추상화에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
추상화는 목적에 필요한 성질을 드러내고 관심 없는 복잡한 세부를 감추어 대상을 간단히 표현한다.
2. 제어 추상화와 자료 추상화의 연결로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
제어 추상화는 복잡한 수행 과정을, 자료 추상화는 복잡한 자료 표현을 간단한 인터페이스로 제공한다.
3. 정보 은닉의 설명으로 가장 알맞은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
정보 은닉은 내부 표현과 구현을 감추어 외부가 공개 연산을 통해서만 대상에 접근하게 한다.
4. 추상 자료형의 정의로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
ADT는 자료와 연산을 하나의 타입으로 선언하고 외부 사용자가 공개 인터페이스로만 자료를 다루게 한다.
5. 추상 자료형의 장점이 아닌 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
ADT는 내부 표현을 숨기는 데 목적이 있다. 수정 용이성, 재사용성, 보안성이 대표 장점이다.
6. pop(push(s,e)) == e가 나타내는 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
원소를 push한 직후 pop하면 그 원소가 나와야 한다는 스택 연산의 의미적 법칙이다.
7. 객체에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
객체는 속성으로 상태를 유지하고 메시지를 받아 메소드로 요청을 처리하며 상태가 바뀔 수 있다.
8. 객체 관련 용어의 연결로 옳지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
메소드는 객체에 대한 요청을 처리하는 서브프로그램이다. 클래스로 생성된 객체가 인스턴스이다.
9. 클래스에 대한 설명으로 알맞은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
클래스는 공통 구조와 동작을 정의하며 이를 통해 생성된 실제 객체를 클래스의 인스턴스라고 한다.
10. 생성자와 소멸자의 비교로 옳지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
생성자는 중복 정의할 수 있지만 소멸자는 중복 정의되지 않는다. 소멸자를 지원하지 않는 언어는 쓰레기 수집기를 사용할 수 있다.
11. C++ 스택 클래스의 소멸자 역할은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
생성자가 new[]로 확보한 배열은 객체 소멸 시 소멸자가 delete[]로 해제해 자원을 정리한다.
12. VTab의 역할로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
메소드 호출 시 수신 객체의 VTab에서 해당 코드 주소를 찾아 실행하므로 실제 객체에 맞는 구현을 선택할 수 있다.
13. 다형성의 정의로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
다형성은 하나의 이름이나 인터페이스를 여러 타입에 적용할 수 있게 한다.
14. 경험적 다형성의 사례는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
경험적 다형성은 실제로 다른 함수나 연산자 구현에 같은 이름을 붙이고 시그니처로 선택한다.
15. 중복 정의와 기본 인수가 충돌할 수 있는 이유는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
f(double b=0.0)과 f()가 함께 있으면 f() 호출에 두 후보가 모두 맞아 시그니처 매칭이 하나를 고르지 못할 수 있다.
16. 매개변수적 다형성에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
C++ 템플릿과 Java 제너릭처럼 타입을 인수로 받아 같은 알고리즘 틀을 여러 타입에 적용한다.
17. 순수 다형성 또는 서브타입 다형성을 결정하는 관계는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
서브타입 다형성은 서브클래스가 부모 클래스의 한 종류라는 IS-A 의미를 만족하는 상속 관계를 이용한다.
18. 다이아몬드 상속 문제에 대한 설명으로 옳지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
다이아몬드 문제는 여러 부모를 거치는 다중 상속 구조에서 공통 조상이 중복될 때 발생한다.
19. 인터페이스와 추상 클래스의 비교로 알맞은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
추상 클래스는 상속 계층의 공통 기반이고, 인터페이스는 서로 다른 클래스가 독립적으로 구현할 수 있는 메소드 규약이다.
20. 트레잇에 대한 설명으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
트레잇은 재사용할 메소드 구현을 포함할 수 있으며 PHP와 Rust 등이 지원한다. Java 8 이후 인터페이스도 이 특성을 반영한다.
댓글
댓글 쓰기