제한된 행위(메서드)를 강제로 수행하도록 하는것.
개발 코드와 객체가 서로 통신하는 접점 역할을 한다.
개발 코드가 인터페이스의 메서드를 호출하면 인터페이스는 객체의 메서드를 호출한다.
따라서 개발 코드는 객체의 내부구조를 알 필요가 없고 인터페이스의 메서드만을 알고 있으면 된다.
접근제어자 interface 인터페이스이름 {
[public static final] 반환타입 상수이름 = 값; // 상수 필드(Constant Field)
[public abstract] 반환타입 메서드이름(매개변수); // 추상 메서드(Abstract Method)
// 자바8 추가
[public] default 반환타입 매서드이름(매개변수); // 디폴트 메서드(Default Method)
// 자바8 추가
[public] static 반환타입 메서드이름(매개변수); // 정적 메서드(Static Method)
}
상수 필드는 [ public static final ]
생략 가능. 상수이름은 대문자로 작성하는것이 관례. 반드시 초기값을 대입해야 한다.
추상 메서드는 [ public abstract ]
생략 가능.
디폴트 메서드는 [ public ]
생략 가능. 기존 인터페이스를 확장해서 새로운 기능을 추가하기 위한 목적.
정적 메서드는 [ public ]
생략 가능. 객체 생성없이 인터페이스만으로 호출 가능.
상수
와 메서드
만을 멤버로 가진다. (필드와 생성자를 가질수 없다)
생성자를 가질수 없으므로, new 연산자로 인스턴스를 생성할 수 없다.
Java 8이후부터 디폴트(default) 메서드
와 정적(static) 메서드
선언이 가능하다
개발 코드에서 인터페이스는 클래스의 필드
, 생성자
및 메서드의 매개변수
그리고 생성자 또는 메서드의 지역 변수
로 선언될 수 있다.
class 클래스이름 implements 인터페이스이름 {
@Override
반환타입 메소드이름() {
......
}
}
ex) 인터페이스를 활용한 예시
public interface RemoteControl {
// 상수 필드
int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
// 추상 메서드
void turnOn();
void turnOff();
void setVolume(int volume);
// 디폴트 메서드
dafault void setMute(boolean mute) {
if(mute) {
System.out.println("무음 처리합니다");
}else {
System.out.println("무음 해제합니다");
}
}
// 정적 메서드
static void changeBattery() {
System.out.println("건전지를 교환합니다");
}
}
public class Television implements RemoteControl {
// 필드
private int volume;
// 추상 메서드 구현
public void turnOn() {
System.out.println("TV를 켠다.");
}
public void turnOff() {
System.out.println("TV를 끈다.");
}
public void setVolume(int volume) {
if(volume > RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
} else if(volume < RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
} else {
this.volume = volume;
}
System.out.println("현재 TV 볼룸 = " + this.volume);
}
}
public class RemoteControlExample {
public static void main(String[] args) {
RemoteControl rc;
rc = new Television();
}
}
하나 이상의 추상 메서드
를 포함하는 클래스.
반드시 사용해야하는 메서드를 추상클래스 내부의 추상메서드로 선언 할 경우에, 추상클래스를 상속받은 모든 클래스에서 추상메서드를 반드시 재 정의해야한다.
즉 객체 지향의 특징인 다형성을 가지는 메서드의 집합을 정의 할 수 있게 해준다.
abstract class 클래스이름 {
// 필드
// 생성자
[접근제한자] abstract 반환타입 메소드이름 (매개변수, ...); // 추상 메서드
}
new 연산자로 인스턴스를 생성할 수 없다. (단 생성자
는 가질 수 있다)
따라서 상속받은 자식클래스에서 추상메서드를 구현하고 인스턴스 생성할 수 있다.
abstract
키워드가 포함된 메서드 없이, abstract 키워드를 클래스에만 추가해도 추상클래스가 된다.
단 이때도 new 연산자로 인스턴스를 생성할 수 없다.
abstract
키워드가 포함된 메서드가 1개라도 있다면 클래스는 무조건 추상클래스가 되어야한다.
인터페이스와는 다르게 static
이나 final
이 아닌 다른 필드(field)도 지정 할 수 있다.
인터페이스와는 다르게 public
, protected
, private
, final
메서드(method)를 가질수 있다.
class 클래스이름 extends 추상클래스이름 {
@Override
반환타입 메소드이름() {
......
}
}
ex) 추상 클래스를 활용한 예시
public abstract class Phone { // 추상 클래스
// 필드
public String owner;
// 생성자
public Phone(String owner) {
this.owner = owner;
}
// 메서드
public void turnOn() {
System.out.println("폰 전원을 켭니다");
}
public void turnOff() {
System.out.println("폰 전원을 끕니다");
}
}
public class SmartPhone extends Phone {
// 생성자
public SmartPhone(String owner) {
super(owner);
}
// 메서드
public void internetSearch() {
System.out.println("인터넷 검색을 합니다");
}
}
public class PhoneExample {
public static void main(String[] args) {
// Phone phone = new Phone(); // 추상클래스 인스턴스 생성 불가능
SmartPhone smartPhone = new SmartPhone("홍길동");
smartPhone.turnOn(); // 추상클래스의 메서드
smartPhone.turnOff(); // 추상클래스의 메서드
smartPhone.internetSearch();
}
}
ex) 추상 메서드를 활용한 예시
public abstract class Animal { // 추상 클래스
public String kind;
public void breathe() { // 일반 메서드
System.out.println("숨을 쉽니다");
}
public abstract void sound(); // 추상 메서드
}
public class Dog extends Animal {
public Dog() {
this.kind = "포유류";
}
@Override
public void sound() { // 추상 메서드 재정의
System.out.println("멍멍");
}
}
public class AnimalExample {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // 멍멍
Animal animal = null;
animal = new Dog(); // 자동 타입변환
animal.sound();
animalSound(new Dog()); // 메서드 다형성
}
public static void animalSound(Animal animal) {
animal.sound(); // 재정의 된 메서드 호출
}
}
추상클래스는 추상메서드
, 생성자
, 필드
, 일반메서드
를 포함할 수 있다.
인터페이스는 추상메서드
, 상수 필드
를 포함할 수 있다. 구현부가 있는 메서드를 포함 못한다.
공통점 : 인스턴스화가 불가능. 구현부가 없는 메서드 및 구현부가 있는 메서드 모두 포함할 수 있다.
추상클래스는 추상메서드
, 생성자
, 필드
, 일반메소드
를 포함할 수 있다. static이나 final말고 다른 필드를 가질수 있다. public
, protected
, private
메서드를 가질수있다.
인터페이스는 추상메서드
, 상수 필드
를 포함 할 수 있다.
추상클래스는 상속을 받은 다음에 기능을 사용하고 확장
하는것에 목적을 둔다.
인터페이스는 미완성된 행위(메소드)의 구현을 강제
하는것에 목적을 둔다.
인터페이스 | abstract 클래스 | 클래스 | |
---|---|---|---|
선언시 사용하는 예약어 | interface | abstract class | class |
구현이 안된 메소드 포함 가능 여부 | 가능 (필수적) | 가능 | 불가 |
구현된 메소드 포함 가능 여부 | 가능 | 가능 | 가능 (필수적) |
static 메소드 선언 가능 여부 | 가능 | 가능 | 가능 |
final 메소드 선언 가능 여부 | 불가 | 가능 | 가능 |
상속(extends) 가능 여부 | 불가 | 가능 | 가능 |
구현(implements) 가능 여부 | 가능 | 불가 | 불가 |
인터페이스 | abstract 클래스 | 클래스 | |
---|---|---|---|
선언시 사용하는 예약어 | interface | abstract class | class |
구현이 안된 메소드 포함 가능 여부 | 가능 (필수적) | 가능 | 불가 |
구현된 메소드 포함 가능 여부 | 불가 | 가능 | 가능 (필수적) |
static 메소드 선언 가능 여부 | 불가 | 가능 | 가능 |
final 메소드 선언 가능 여부 | 불가 | 가능 | 가능 |
상속(extends) 가능 여부 | 불가 | 가능 | 가능 |
구현(implements) 가능 여부 | 가능 | 불가 | 불가 |
ex) 인터페이스 및 추상클래스를 활용한 예시
interface MoveAble {
// public abstract 가 생략
void 위();
void 아래();
void 왼쪽();
void 오른쪽();
}
interface MoveAble2 {
// public abstract 가 생략
void 위();
void 아래();
void 왼쪽();
void 오른쪽();
void 숨기();
}
// 일반클래스의 경우 인터페이스인 MoveAble을 implements하고 구현
// 추상클래스의 경우 인터페이스인 MoveAble을 implements하고 구현은 서브클래스로 위임
// 하지만 추상클래스와 서브클래스의 구현할 내용이 같다면 추상클래스에서 구현을 해도된다.
abstract class 사나운동물 implements MoveAble {
abstract void 공격(); // 미완성 메서드
@Override
public void 위() {
System.out.println("위로 이동");
}
@Override
public void 아래() {
System.out.println("아래로 이동");
}
@Override
public void 왼쪽() {
System.out.println("왼쪽으로 이동");
}
@Override
public void 오른쪽() {
System.out.println("오른쪽으로 이동");
}
}
abstract class 온순한동물 implements MoveAble2{
abstract void 채집(); // 미완성 메서드
@Override
public void 위() {
System.out.println("위로 이동");
}
@Override
public void 아래() {
System.out.println("아래로 이동");
}
@Override
public void 왼쪽() {
System.out.println("왼쪽으로 이동");
}
@Override
public void 오른쪽() {
System.out.println("오른쪽으로 이동");
}
@Override
public void 숨기() {
System.out.println("땅바닥으로 이동");
}
}
class 원숭이 extends 온순한동물 {
@Override // 어노테이션 : JVM이 실행시에 분석해서 확인
void 채집() {
System.out.println("바나나 채집");
}
}
class 소 extends 온순한동물 {
@Override
void 채집() {
System.out.println("풀 채집");
}
}
class 호랑이 extends 사나운동물 {
@Override
void 공격() {
System.out.println("할퀴기 공격");
}
}
class 사자 extends 사나운동물 {
@Override
void 공격() {
System.out.println("물기 공격");
}
}
public class OOPEx09 {
// 다형성(오버로딩)
static void 조이스틱(온순한동물 u) {
u.채집();
u.숨기();
u.위();
u.아래();
u.오른쪽();
u.왼쪽();
System.out.println("========================");
}
// 다형성(오버로딩)
static void 조이스틱(사나운동물 s) {
s.공격();
s.위();
s.아래();
s.오른쪽();
s.왼쪽();
System.out.println("========================");
}
public static void main(String[] args) {
소 u1 = new 소();
조이스틱(u1);
원숭이 u2 = new 원숭이();
조이스틱(u2);
호랑이 u3 = new 호랑이();
조이스틱(u3);
사자 u4 = new 사자();
조이스틱(u4);
}
}
출처
- 이지업 컨텐츠 내의 데어프로그래밍 자바강의
- 자바의 신 (책)
- 이것이 자바다 (책)