- B Tree & B+ Tree
- Heap Sort
- 웹 통신의 큰 흐름
- 인터럽트
- 정규화에 대해서 | 정규화 탄생 배경 | 정규화란 무엇인가
- 자바 - 추상 클래스, 인터페이스, 차이
B Tree & B+ Tree
B Tree
데이터베이스, 파일 시스템에서 널리 사용되는 트리 자료구조의 일종이다.
이진 트리를 확장해서, 더 많은 수의 자식을 가질 수 있게 일반화 시킨 것이 B-Tree
자식 수에 대한 일반화를 진행하면서, 하나의 레벨에 더 저장되는 것 뿐만 아니라 트리의 균형을 자동으로 맞춰주는 로직까지 갖추었다. 단순하고 효율적이며, 레벨로만 따지면 완전히 균형을 맞춘 트리다.
대량의 데이터를 처리해야 할 때, 검색 구조의 경우 하나의 노드에 많은 데이터를 가질 수 있다는 점은 상당히 큰 장점이다. 대량의 데이터는 메모리보다 블럭 단위로 입출력하는 하드디스크 or SSD에 저장해야하기 때문! ex) 한 블럭이 1024 바이트면, 2바이트를 읽으나 1024바이트를 읽으나 똑같은 입출력 비용 발생. 따라서 하나의 노드를 모두 1024바이트로 꽉 채워서 조절할 수 있으면 입출력에 있어서 효율적인 구성을 갖출 수 있다. → B-Tree는 이러한 장점을 토대로 많은 데이터베이스 시스템의 인덱스 저장 방법으로 애용하고 있음
규칙
- 노드의 자료수가 N이면, 자식 수는 N+1이어야 함
- 각 노드의 자료는 정렬된 상태여야함
- 루트 노드는 적어도 2개 이상의 자식을 가져야함
- 루트 노드를 제외한 모든 노드는 적어도 M/2개의 자료를 가지고 있어야함
- 외부 노드로 가는 경로의 길이는 모두 같음.
- 입력 자료는 중복 될 수 없음
B+ Tree
데이터의 빠른 접근을 위한 인덱스 역할만 하는 비단말 노드(not Leaf)가 추가로 있음
(기존의 B-Tree와 데이터의 연결리스트로 구현된 색인구조)
B-Tree의 변형 구조로, index 부분과 leaf 노드로 구성된 순차 데이터 부분으로 이루어진다. 인덱스 부분의 key 값은 leaf에 있는 key 값을 직접 찾아가는데 사용함.
장점
블럭 사이즈를 더 많이 이용할 수 있음 (key 값에 대한 하드디스크 액세스 주소가 없기 때문)
leaf 노드끼리 연결 리스트로 연결되어 있어서 범위 탐색에 매우 유리함
단점
B-tree의 경우 최상 케이스에서는 루트에서 끝날 수 있지만, B+tree는 무조건 leaf 노드까지 내려가봐야 함
B-Tree & B+ Tree
B-tree는 각 노드에 데이터가 저장됨
B+tree는 index 노드와 leaf 노드로 분리되어 저장됨
(또한, leaf 노드는 서로 연결되어 있어서 임의접근이나 순차접근 모두 성능이 우수함)
B-tree는 각 노드에서 key와 data 모두 들어갈 수 있고, data는 disk block으로 포인터가 될 수 있음
B+tree는 각 노드에서 key만 들어감. 따라서 data는 모두 leaf 노드에만 존재
B+tree는 add와 delete가 모두 leaf 노드에서만 이루어짐
Heap Sort
void heapify(int arr[], int idx, int heapSize){
int nextIdx = idx*2;
if(nextIdx > heapSize){
return;
}
if(nextIdx + 1 <= heapSize){
if(arr[nextIdx] < arr[nextIdx+1]){
nextIdx += 1;
}
}
if(arr[nextIdx] > arr[idx]){
int tmp = arr[idx];
arr[idx] = arr[nextIdx];
arr[nextIdx] = tmp;
heapify(arr, nextIdx, heapSize);
}
}
void heapSort(int arr[]){
int heapSize = n;
for(int i=n/2;i>0;--i){
heapify(arr, i, n);
}
while(heapSize > 0){
int tmp = arr[1];
arr[1] = arr[heapSize];
arr[heapSize] = tmp;
--heapSize;
heapify(arr, 1, heapSize);
}
}
- 배열과 min, max heap 개념을 이용해서 힙 정렬을 구현 할 수 있다.
- in-place 기법이며 공간복잡도는 O(n) 이다.
- 힙 자료구조 특성에서의 부모와 자식관계는 배열의 인덱스로 나타날 수 있다.
- 힙 자료구조가 완전이진트리의 특성을 지니기 때문에 가능하며, 부모 인덱스가 i라면 왼쪽 자식은 2*i, 오른쪽 자식은 2*i + 1이다.
( 따라서 배열의 인덱스는 항상 1부터 시작하여야 하며, arr[1]이 루트가 된다. ) - heapify 함수가 logn 소요 되고, n개의 배열을 정렬하여야 하기 때문에 총 시간 복잡도는 n log n이 된다.
- 힙 규칙을 만족하는 트리가 완성되면, 루트서 부터 출력하거나 원래 배열로 옮기면서 pop 해주고,
다시 heapify가 호출하면서 순서대로 정렬할 수 있다.
웹 통신의 큰 흐름
in 브라우저
- url 에 입력된 값을 브라우저 내부에서 결정된 규칙에 따라 그 의미를 조사한다.
- 조사된 의미에 따라 HTTP Request 메시지를 만든다.
- 만들어진 메시지를 웹 서버로 전송한다.
이 때 만들어진 메시지 전송은 브라우저가 직접하는 것이 아니다. 브라우저는 메시지를 네트워크에 송출하는 기능이 없으므로 OS에 의뢰하여 메시지를 전달한다. 우리가 택배를 보낼 때 직접 보내는게 아니라, 이미 서비스가 이루어지고 있는 택배 시스템(택배 회사)을 이용하여 보내는 것과 같은 이치이다. 단, OS에 송신을 의뢰할 때는 도메인명이 아니라 ip주소로 메시지를 받을 상대를 지정해야 하는데, 이 과정에서 DNS서버를 조회해야 한다.
in 프로토콜 스택, LAN 어댑터
- 프로토콜 스택(운영체제에 내장된 네트워크 제어용 소프트웨어)이 브라우저로부터 메시지를 받는다.
- 브라우저로부터 받은 메시지를 패킷 속에 저장한다.
- 그리고 수신처 주소 등의 제어정보를 덧붙인다.
- 그런 다음, 패킷을 LAN 어댑터에 넘긴다.
- LAN 어댑터는 패킷을(?) 전기신호로 변환시킨다.
- 신호를 LAN 케이블에 송출시킨다.
프로토콜 스택은 통신 중 오류가 발생했을 때, 이 제어 정보를 사용하여 고쳐 보내거나, 각종 상황을 조절하는 등 다양한 역할을 하게 된다. 네트워크 세계에서는 비서가 있어서 우리가 비서에게 물건만 건네주면, 받는 사람의 주소와 각종 유의사항을 써준다! 여기서는 프로토콜 스택이 비서의 역할을 한다고 볼 수 있다.
in 허브, 스위치, 라우터
- LAN 어댑터가 송신한 패킷은 스위칭 허브를 경유하여 인터넷 접속용 라우터에 도착한다.
- 라우터는 패킷을 프로바이더(통신사)에게 전달한다.
- 인터넷으로 들어가게 된다.
in 액세스 회선, 프로바이더
- 패킷은 인터넷의 입구에 있는 액세스 회선(통신 회선)에 의해 POP(Point Of Presence, 통신사용 라우터)까지 운반된다.
- POP 를 거쳐 인터넷의 핵심부로 들어가게 된다.
- 수 많은 고속 라우터들 사이로 패킷이 목적지를 향해 흘러가게 된다.
in 방화벽, 캐시서버
- 패킷은 인터넷 핵심부를 통과하여 웹 서버측의 LAN 에 도착한다.
- 기다리고 있던 방화벽이 도착한 패킷을 검사한다.
- 패킷이 웹 서버까지 가야하는지 가지 않아도 되는지를 판단하는 캐시서버가 존재한다.
굳이 서버까지 가지 않아도 되는 경우를 골라낸다. 액세스한 페이지의 데이터가 캐시서버에 있으면 웹 서버에 의뢰하지 않고 바로 그 값을 읽을 수 있다. 페이지의 데이터 중에 다시 이용할 수 있는 것이 있으면 캐시 서버에 저장된다.
in 웹 서버
- 패킷이 물리적인 웹 서버에 도착하면 웹 서버의 프로토콜 스택은 패킷을 추출하여 메시지를 복원하고 웹 서버 애플리케이션에 넘긴다.
- 메시지를 받은 웹 서버 애플리케이션은 요청 메시지에 따른 데이터를 응답 메시지에 넣어 클라이언트로 회송한다.
- 왔던 방식대로 응답 메시지가 클라이언트에게 전달된다.
인터럽트(Interrupt)
정의
프로그램을 실행하는 도중에 예기치 않은 상황이 발생할 경우 현재 실행 중인 작업을 즉시 중단하고, 발생된 상황을 우선 처리한 후 실행 중이던 작업으로 복귀하여 계속 처리하는 것
지금 수행 중인 일보다 더 중요한 일(ex. 입출력, 우선 순위 연산 등)이 발생하면 그 일을 먼저 처리하고 나서 하던 일을 계속해야한다.
외부/내부 인터럽트는 CPU의 하드웨어 신호에 의해 발생
소프트웨어 인터럽트는 명령어의 수행에 의해 발생
입출력 장치, 타이밍 장치, 전원 등 외부적인 요인으로 발생
전원 이상, 기계 착오, 외부 신호, 입출력
외부 인터럽트
Trap이라고 부르며, 잘못된 명령이나 데이터를 사용할 때 발생
0으로 나누기가 발생, 오버플로우, 명령어를 잘못 사용한 경우 (Exception)
내부 인터럽트
프로그램 처리 중 명령의 요청에 의해 발생한 것 (SVC 인터럽트)
사용자가 프로그램을 실행시킬 때 발생
소프트웨어 이용 중에 다른 프로세스를 실행시키면 시분할 처리를 위해 자원 할당 동작이 수행된다.
소프트웨어 인터럽트
인터럽트 발생 처리 과정
주 프로그램이 실행되다가 인터럽트가 발생했다.
현재 수행 중인 프로그램을 멈추고, 상태 레지스터와 PC 등을 스택에 잠시 저장한 뒤에 인터럽트 서비스 루틴으로 간다. (잠시 저장하는 이유는, 인터럽트 서비스 루틴이 끝난 뒤 다시 원래 작업으로 돌아와야 하기 때문)
만약 인터럽트 기능이 없었다면, 컨트롤러는 특정한 어떤 일을 할 시기를 알기 위해 계속 체크를 해야 한다. (이를 **폴링(Polling)**이라고 한다)
폴링을 하는 시간에는 원래 하던 일에 집중할 수가 없게 되어 많은 기능을 제대로 수행하지 못하는 단점이 있었다.
즉, 컨트롤러가 입력을 받아들이는 방법(우선순위 판별방법)에는 두가지가 있다.
사용자가 명령어를 사용해 입력 핀의 값을 계속 읽어 변화를 알아내는 방식
인터럽트 요청 플래그를 차례로 비교하여 우선순위가 가장 높은 인터럽트 자원을 찾아 이에 맞는 인터럽트 서비스 루틴을 수행한다. (하드웨어에 비해 속도 느림)
폴링 방식
MCU 자체가 하드웨적으로 변화를 체크하여 변화 시에만 일정한 동작을 하는 방식
- Daisy Chain
- 병렬 우선순위 부여
인터럽트 방식
인터럽트 방식은 하드웨어로 지원을 받아야 하는 제약이 있지만, 폴링에 비해 신속하게 대응하는 것이 가능하다. 따라서 **'실시간 대응'**이 필요할 때는 필수적인 기능이다.
즉, 인터럽트는 발생시기를 예측하기 힘든 경우에 컨트롤러가 가장 빠르게 대응할 수 있는 방법이다.
정규화에 대해서
1. 정규화는 어떤 배경에서 생겨났는가?
한 릴레이션에 여러 엔티티의 애트리뷰트들을 혼합하게 되면 정보가 중복 저장되며, 저장 공간을 낭비하게 된다. 또 중복된 정보로 인해 갱신 이상이 발생하게 된다. 동일한 정보를 한 릴레이션에는 변경하고, 나머지 릴레이션에서는 변경하지 않은 경우 어느 것이 정확한지 알 수 없게 되는 것이다. 이러한 문제를 해결하기 위해 정규화 과정을 거치는 것이다.
1-1. 갱신 이상에는 어떠한 것들이 있는가?
-
삽입 이상(insertion anomalies) 원하지 않는 자료가 삽입된다든지, 삽입하는데 자료가 부족해 삽입이 되지 않아 발생하는 문제점을 말한다.
-
삭제 이상(deletion anomalies) 하나의 자료만 삭제하고 싶지만, 그 자료가 포함된 튜플 전체가 삭제됨으로 원하지 않는 정보 손실이 발생하는 문제점을 말한다.
-
수정(갱신)이상(modification anomalies) 정확하지 않거나 일부의 튜플만 갱신되어 정보가 모호해지거나 일관성이 없어져 정확한 정보 파악이 되지 않는 문제점을 말한다.
2. 그래서 정규화란 무엇인가?
관계형 데이터베이스에서 중복을 최소화하기 위해 데이터를 구조화하는 작업이다. 좀 더 구체적으로는 불만족스러운 나쁜 릴레이션의 애트리뷰트들을 나누어서 좋은 작은 릴레이션으로 분해하는 작업을 말한다. 정규화 과정을 거치게 되면 정규형을 만족하게 된다. 정규형이란 특정 조건을 만족하는 릴레이션의 스키마의 형태를 말하며 제 1 정규형, 제 2 정규형, 제 3 정규형, … 등이 존재한다.
2-1. ‘나쁜' 릴레이션은 어떻게 파악하는가?
엔티티를 구성하고 있는 애트리뷰트 간에 함수적 종속성(Functional Dependency)을 판단한다. 판단된 함수적 종속성은 좋은 릴레이션 설계의 정형적 기준으로 사용된다. 즉, 각각의 정규형마다 어떠한 함수적 종속성을 만족하는지에 따라 정규형이 정의되고, 그 정규형을 만족하지 못하는 정규형을 나쁜 릴레이션으로 파악한다.
2-2. 함수적 종속성이란 무엇인가?
함수적 종속성이란 애트리뷰트 데이터들의 의미와 애트리뷰트들 간의 상호 관계로부터 유도되는 제약조건의 일종이다. X 와 Y 를 임의의 애트리뷰트 집합이라고 할 때, X 의 값이 Y 의 값을 유일하게(unique) 결정한다면 "X 는 Y 를 함수적으로 결정한다"라고 한다. 함수적 종속성은 실세계에서 존재하는 애트리뷰트들 사이의 제약조건으로부터 유도된다. 또한 각종 추론 규칙에 따라서 애트리뷰트들간의 함수적 종속성을 판단할 수 있다. cf> 애트리뷰트들의 관계로부터 추론된 함수적 종속성들을 기반으로 추론 가능한 모든 함수적 종속성들의 집합을 폐포라고 한다.
2-3. 각각의 정규형은 어떠한 조건을 만족해야 하는가?
- 분해의 대상인 분해 집합 D 는 무손실 조인 을 보장해야 한다.
- 분해 집합 D 는 함수적 종속성을 보존해야 한다.
제 1 정규형
애트리뷰트의 도메인이 오직 원자값만을 포함하고, 튜플의 모든 애트리뷰트가 도메인에 속하는 하나의 값을 가져야 한다. 즉, 복합 애트리뷰트, 다중값 애트리뷰트, 중첩 릴레이션 등 비 원자적인 애트리뷰트들을 허용하지 않는 릴레이션 형태를 말한다.
제 2 정규형
모든 비주요 애트리뷰트들이 주요 애트리뷰트에 대해서 완전 함수적 종속이면 제 2 정규형을 만족한다고 볼 수 있다. 완전 함수적 종속이란 X -> Y 라고 가정했을 때, X 의 어떠한 애트리뷰트라도 제거하면 더 이상 함수적 종속성이 성립하지 않는 경우를 말한다. 즉, 키가 아닌 열들이 각각 후보키에 대해 결정되는 릴레이션 형태를 말한다.
제 3 정규형
어떠한 비주요 애트리뷰트도 기본키에 대해서 이행적으로 종속되지 않으면 제 3 정규형을 만족한다고 볼 수 있다. 이행 함수적 종속이란 X - >Y, Y -> Z의 경우에 의해서 추론될 수 있는 X -> Z의 종속관계를 말한다. 즉, 비주요 애트리뷰트가 비주요 애트리뷰트에 의해 종속되는 경우가 없는 릴레이션 형태를 말한다.
BCNF(Boyce-Codd) 정규형
여러 후보 키가 존재하는 릴레이션에 해당하는 정규화 내용이다. 복잡한 식별자 관계에 의해 발생하는 문제를 해결하기 위해 제 3 정규형을 보완하는데 의미가 있다. 비주요 애트리뷰트가 후보키의 일부를 결정하는 분해하는 과정을 말한다.
각 정규형은 그의 선행 정규형보다 더 엄격한 조건을 갖는다.
- 모든 제 2 정규형 릴레이션은 제 1 정규형을 갖는다.
- 모든 제 3 정규형 릴레이션은 제 2 정규형을 갖는다.
- 모든 BCNF 정규형 릴레이션은 제 3 정규형을 갖는다.
수많은 정규형이 있지만 관계 데이터베이스 설계의 목표는 각 릴레이션이 3NF(or BCNF)를 갖게 하는 것이다.
3. 정규화에는 어떠한 장점이 있는가?
-
데이터베이스 변경 시 이상 현상(Anomaly) 제거 위에서 언급했던 각종 이상 현상들이 발생하는 문제점을 해결할 수 있다.
-
데이터베이스 구조 확장 시 재 디자인 최소화 정규화된 데이터베이스 구조에서는 새로운 데이터 형의 추가로 인한 확장 시, 그 구조를 변경하지 않아도 되거나 일부만 변경해도 된다. 이는 데이터베이스와 연동된 응용 프로그램에 최소한의 영향만을 미치게 되며 응용프로그램의 생명을 연장시킨다.
-
사용자에게 데이터 모델을 더욱 의미있게 제공 정규화된 테이블들과 정규화된 테이블들간의 관계들은 현실 세계에서의 개념들과 그들간의 관계들을 반영한다.
4. 단점은 없는가?
릴레이션의 분해로 인해 릴레이션 간의 연산(JOIN 연산)이 많아진다. 이로 인해 질의에 대한 응답 시간이 느려질 수 있다. 조금 덧붙이자면, 정규화를 수행한다는 것은 데이터를 결정하는 결정자에 의해 함수적 종속을 가지고 있는 일반 속성을 의존자로 하여 입력/수정/삭제 이상을 제거하는 것이다. 데이터의 중복 속성을 제거하고 결정자에 의해 동일한 의미의 일반 속성이 하나의 테이블로 집약되므로 한 테이블의 데이터 용량이 최소화되는 효과가 있다. 따라서 정규화된 테이블은 데이터를 처리할 때 속도가 빨라질 수도 있고 느려질 수도 있는 특성이 있다.
5. 단점에서 미루어보았을 때 어떠한 상황에서 정규화를 진행해야 하는가? 단점에 대한 대응책은?
조희를 하는 SQL 문장에서 조인이 많이 발생하여 이로 인한 성능저하가 나타나는 경우에 반정규화를 적용하는 전략이 필요하다.
반정규화(De-normalization, 비정규화)
반정규화는 정규화된 엔티티, 속성, 관계를 시스템의 성능 향상 및 개발과 운영의 단순화를 위해 중복 통합, 분리 등을 수행하는 데이터 모델링 기법 중 하나이다. 디스크 I/O 량이 많아서 조회 시 성능이 저하되거나, 테이블끼리의 경로가 너무 멀어 조인으로 인한 성능 저하가 예상되거나, 칼럼을 계산하여 조회할 때 성능이 저하될 것이 예상되는 경우 반정규화를 수행하게 된다. 일반적으로 조회에 대한 처리 성능이 중요하다고 판단될 때 부분적으로 반정규화를 고려하게 된다.
5-1. 무엇이 반정규화의 대상이 되는가?
- 자주 사용되는 테이블에 액세스하는 프로세스의 수가 가장 많고, 항상 일정한 범위만을 조회하는 경우
- 테이블에 대량 데이터가 있고 대량의 범위를 자주 처리하는 경우, 성능 상 이슈가 있을 경우
- 테이블에 지나치게 조인을 많이 사용하게 되어 데이터를 조회하는 것이 기술적으로 어려울 경우
5-2. 반정규화 과정에서 주의할 점은?
반정규화를 과도하게 적용하다 보면 데이터의 무결성이 깨질 수 있다. 또한 입력, 수정, 삭제의 질의문에 대한 응답 시간이 늦어질 수 있다.
JAVA - 추상 클래스와 인터페이스
추상 클래스란?
-
추상 클래스는 미완성된 클래스이다.
-
미완성된 클래스는 미완성된 메소드인 추상 메소드를 포함하고 있다.
-
추상 클래스는 혼자로는 클래스의 역할을 다 못하지만, 새로운 클래스를 작성하는 데 있어 그 바탕이 되는 부모 클래스로서의 중요한 의미를 갖는다. 왜냐하면 클래스를 작성함에 있어서 어느정도 작성된 상태에서 시작할 수 있기 때문이다.
-
클래스 앞에 abstract 키워드를 붙인다.
- abstract 키워드가 있는 클래스라고 모두 구현해야 하는 것은 아니다. 왜냐하면 단지 공유의 목적으로 abstract class를 만드는 경우도 있기 때문이다.
[추상 클래스의 목적]
- 기존의 클래스에서 공통된 부분을 추상화하여 상속하는 클래스에게 구현을 강제화한다. 메소드의 동작은 구현하는 자식 클래스에게 위임한다.
- 공유의 목적을 갖고 있다.
[추상 클래스의 특징]
-
추상 클래스는 추상 메소드가 아닌 일반 메소드, 멤버도 포함할 수 있다. 하지만 추상 메소드를 하나라도 포함하고 있다면 추상 클래스로 선언해야 한다.
-
추상 클래스는 동작이 정의되어 있지 않은 추상 메소드를 포함하고 있으므로 인스턴스를 생성할 수 없다.
인터페이스란?
- 인터페이스는 인터페이스를 구현하는 모든 클래스에 대해 특정한 메소드가 반드시 존재하도록 강제한다.
- 인터페이스의 목적은 구현 객체가 같은 동작을 한다는 것을 보장하는 것이다.
- 일종의 추상 클래스다. 하지만 추상 클래스보다 추상화 정도가 높아서 추상 메소드 이외의 일반 메소드나 멤버 변수를 구성원으로 가질 수 없다. 오직 추상 메소드와 상수만 멤버로 가질 수 있으며, 그 외의 요소는 허용하지 않는다.
추상 클래스를 부분적으로만 완성된 미완성 설계도라고 한다면 인터페이스는 구현된 것이 아무것도 없는 기본 설계도라 할 수 있다.
- 제약 사항
- 모든 멤버 변수는 public static final 이어야 하며, 생략 가능.
- 모든 메소드는 public abstract 이어야 하며, 생략 가능.
- JDK 1.8부터 인터페이스에 static 메소드와 디폴트 메소드의 추가를 허용했다.
[인터페이스의 상속]
- 인터페이스는 인터페이스로부터만 상속(extends) 받을 수 있다. 클래스와는 달리 다중 상속, 즉 여러 개의 인터페이스로부터 상속 받는 것이 가능하다.
- 클래스에서 여러 인터페이스를 다중 구현하는 것 또한 가능하다.
[인터페이스의 구현]
- 추상 클래스와 마찬가지로 자신이 직접 인스턴스를 생성할 수 없다. 따라서 인터페이스가 포함하고 있는 추상 메소드를 구현해 줄 클래스를 작성해야 한다.
- 상속은 클래스를 확장한다는 의미의 키워드인 extends를 사용하며, 인터페이스는 구현한다는 의미의 키워드인 implements를 사용한다.
[클래스를 이용한 다중 상속의 문제점]
다중 상속을 허용할 경우, 발생할 수 있는 문제는 메소드 출처의 모호성이다.
주석을 달아놓은 2에서 MyPet 클래스의 인스턴스인 pet이 cry() 메소드를 호출하면 이 메소드가 Dog 클래스의 cry() 메소드인지, Cat 클래스의 cry() 메소드인지 구분할 수 없는 모호성이 생긴다.
이와 같은 이유로 자바에서 다중 상속을 지원하지 않는다.
하지만, 인터페이스를 이용해 다중 구현을 하게되면 위와 같은 메소드 호출의 모호성을 방지할 수 있다.
Cat, Dog 인터페이스를 동시에 구현한 Pet 클래스에서만 cry() 메소드를 정의하므로, 앞의 예제에서 발생한 메소드 호출의 모호성이 없다.
[인터페이스를 통한 다형성]
자손 클래스의 인스턴스를 조상 타입의 참조 변수로 참조하는 것이 가능하다.
인터페이스도 인터페이스를 구현한 클래스의 조상이라고 할 수 있으므로, 해당 인터페이스 타입의 참조 변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있다.
[장점]
- 대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화가 가능하다.
- 클래스의 작성과 인터페이스의 구현을 동시에 진행할 수 있으므로, 개발 시간을 단축할 수 있다.
- 클래스와 클래스 간의 관계를 인터페이스로 연결하면 클래스마다 독립적인 프로그래밍이 가능하다.
추상 클래스와 인터페이스의 차이점
- 인터페이스
- 클래스가 아니며, 클래스와 관련이 없다.
- 추상 메소드와 상수만을 멤버로 가진다.
- 한 개의 클래스가 여러 인터페이스를 구현할 수 있다. (다중 구현 가능.)
- Java 8부터 default 메소드가 추가되었다.
- default 키워드가 붙은 메소드는 구현할 수 있으며(일반 메소드처럼), 자식 클래스에서는 이를 오버라이딩할 수 있다.
- 인터페이스가 변경되면 이를 구현하는 모든 클래스들이 해당 메소드를 다시 구현해야하는 번거로운 문제가 있었다. 이런 문제를 해결하기 위하여 인터페이스에 메소드를 구현할 수 있도록 변경되었다.
- Java 8부터 static 메소드가 추가되었다.
- 인터페이스에 static 메소드를 선언 가능하게 함으로써, 간단한 기능을 가지는 유틸리티성 인터페이스를 만들 수 있게 되었다.
- 목적 : 구현 객체의 같은 동작을 보장하기 위해 사용한다.
- 추상 클래스
- 클래스이며, 클래스와 관련이 있다. (주로 베이스 클래스로 사용)
- 추상 메소드 및 일반 메소드와 멤버도 포함할 수 있다.
- 한 개의 클래스가 여러 개의 클래스를 상속받을 수 없다. (다중 상속 불가능.)
- 상속을 받아 기능을 확장시키는 데 목적이 있다.
- 목적 : 기존의 클래스에서 공통된 부분을 추상화하여 상속하는 클래스에게 구현을 강제화한다. 메소드의 동작은 구현하는 자식 클래스로 위임한다.
- 공유의 목적.