본문 바로가기

STUDY/Java

[JAVA] 추상 클래스, 인터페이스

 
 

01 추상 클래스

1. 추상클래스(abstract class) (<-> concrete class)

- 함수의 구현부 ( {} )가 없는 함수

- 추상 메소드가 1개 이상 존재하면 추상 클래스

- 추상 클래스를 상속받으면 반드시 오버라이딩(Overriding)을 해야 함

- 선언만 하며 abstract 예약어를 사용

- 추상 클래스는 new라는 명령어를 사용 안함 -> 객체를 만들 때 까다로움

- extends: 상속 키워드

- ( {} ) 대신 ( ; ) 를 사용

ex) abstract int add (int x, int y);

int add(int x, int y) {} // 추상 메서드가 아님 (코드만 없을 뿐 {}인 body는 있기 때문에)

- 오버라이딩

java.util 패키지 > Calendar 클래스 (추상클래스)

 

* 자동으로 오버라이딩 생성

 

 

ex) 추상 클래스 상속하기

 

추상 메서드는 기울임꼴로 표현

* Computer는 추상 클래스

* display(), typing()은 추상 메서드

* DeskTop은 Computer 클래스를 상속받은 일반 클래스

* NoteBook은 Computer 클래스를 상속받은 추상 클래스

* MyNoteBook은 NoteBook 클래스를 상속받은 일반 클래스

 

ex) Compuper.java

package abstractex;

public abstract class Computer {     // Computer 추상 클래스
	public abstract void display();
	public abstract void typing();
	public void turnOn(){
		System.out.println("전원을 켭니다");
	}
	public void turnOff(){
		System.out.println("전원을 끕니다.");
	}
}
 

① 6행, 9행: Computer를 상속받는 클래스 중 turnOn()과 turnOff() 구현 코드는 공통

② 4행, 5행: display()와 typing()은 하위 클래스에 따라 구현이 달라질 수 있으므로 DeskTop과 NoteBook 클래스에서 각각 구현

* 상위 클래스에서는 하위 클래스도 공통으로 사용할 메서드를 구현하고 하위 클래스마다 다르게 구현할 메서드는 추상 메서드로 선언

 

ex) DeskTop.java

package abstractex;

public class DeskTop extends Computer {
	@Override
	public void display() {
		System.out.println("Desktop display()");
	}

	@Override
	public void typing() {
		System.out.println("DeskTop typing()");
	}
}
 

① 4행, 9행: Desktop은 concrete class(일반 클래스)이므로 추상 메서드를 모두 구현해야 함

② 4행, 9행: display()와 typing() 모두 구현

 

ex) NoteBook.java

package abstractex;

public abstract class NoteBook extends Computer{
	@Override
	public void display() {
		System.out.println("Notebook display()");
	}
}
 

① 3행: NoteBook은 추상클래스이므로 추상메서드를 모두 구현하지 않고 하나만 구현하여 추상 클래스가 됨

② 5행: display()만 구현하고 typing()은 구현하지 않음

③ 3행: 추상 메서드를 하나 가지고 있기 때문에 추상 클래스이므로 abstract 예약어 사용

 

ex) MyNoteBook.java

package abstractex;

public class MyNoteBook extends NoteBook {
	@Override
	public void typing() {
		System.out.println("MyNoteBook typing()");
	}
}
 

① 3행: MyNoteBook은 일반 클래스이므로 추상 메서드를 모두 구현해야 함

② 5행: MyNoteBook의 상위 클래스는 NoteBook 클래스 이므로 typing() 메서드만 구현하면 모든 추상 메서드가 구현됨

③ 3행: 추상 클래스가 아니므로 abstract 예약어를 사용 x

 

 


 

2. final 예약어

- final 예약어를 사용하면 더 이상 수정 불가능

사용 위치
설명
변수
final 변수는 상수를 의미, 값의 수정 불가능
메서드
final 메서드는 하위 클래스에서 재정의 불가능
클래스
final 클래스는 상속 불가능

 

 


 

02 인터페이스

1. 인터페이스(interface)

- 클래스 혹은 프로그램이 제공하는 기능을 명시적으로 선언하는 역할

- 추상 메서드와 상수로만 이루어짐, 일반 메서드는 없음

- 모두 추상 메서드 이므로 추상 클래스라고 할 수 있고 Overriding이 반드시 필요

- 인터페이스는 다중 상속이 가능

- 인터페이스로 인스턴스를 생성할 수 없음

- implements: 인터페이스 상속 키워드

 

1) 인터페이스 만들기

① 패키지에서 오른쪽 마우스 버튼 > [New] > [Interface]

② Name에 인터페이스 이름 설정


2) 인터페이스 구현하기

* 모든 변수는 public static final 예약어를 쓰지 않아도 무조건 상수로 인식

* 모든 추상 메서드는 public abstract 예약어를 명시적으로 쓰지 않아도 컴파일 과정에서 자동으로 추상 메서드로 변환

 


 

3) 인터페이스 요소

① 디폴트 메서드(default method): 기본으로 제공되는 메서드, 인터페이스에서 구현 코드까지 작성한 메서드

- 인터페이스에서 구현하지만 이후 인터페이스를 구현한 클래스가 생성되면 그 default 예약어를 사용

- 일반 메서드와 똑같이 구현하지만 자료형 앞에 default만 추가

* 만약 이미 인터페이스에 구현되어 있는 디폴트 메서드가 새로 생성한 클래스에서 원하는 기능과 맞지 않는다면 하위 클래스에서 디폴트 메서드를 재정의할 수 있다

 

② 정적 메서드(static method): 인스턴스 생성과 상관없이 사용할 수 있는 메서드

- static 예약어를 사용

- 클래스 생성과 무관하게 사용 가능

- 인터페이스 이름으로 직접 참조하여 사용

 

③ Private method: 인터페이스를 구현한 클래스에서 사용하거나 재정의 불가능

- 기존에 구현된 코드를 변경하지 않고 인터페이스를 구현한 클래스에서 공통으로 사용하는 경우에 Private 메서드로 구현하면 코드 재사용성을 높일 수 있음

- 클라이언트 프로그램에 제공할 기본 기능을 private 메서드로 구현하기도 함

- 코드를 모두 구현해야 하므로 추상 메서드에 private 예약어를 사용할 순 없지만 static 예약어는 함께 사용 가능

- 자바 9부터 사용 가능

 


 

4) 인터페이스 상속

- 인터페이스간의 상속은 기능을 상속하는 것이 아니므로 형 상속이라고 한다

- 클래스의 경우, 하나의 클래스만 상속받을 수 있지만 인터페이스의 경우, 여러 개를 동시에 상속받을 수 있다