인터페이스
인터페이스는 추상화에서 가장 핵심적인 역할을 담당한다고 한다.
종종 인터페이스라고 말하는데 , 프로그래밍에서는 인터페이를 "서로 다른 두 시스템, 장치, 소프트웨어 따위를 서로 이어주는 부분 또는 그런 접속 장치" 라고 한다.
쉽게 비유하면, 우리가 에어컨을 사용할 때를 생각하면 된다.
에어컨이 어떤 냉매를 쓰고, 얼마나 펌프질 하고, 몇 칼로리의 열을 흡수, 방출하는지 알 길이 없다.
그냥 액정에 표시된 온도를 보고, 버튼을 눌러 작동시키는 것이다.
여기서 액정과 버튼이 인터페이스인 것이다.
액정의 숫자와 버튼이 어떤 값을 가지는지는 모르지만, 여튼 누르면 작동된다. -> 추상화 (상위 클래스)
눌린 버튼에 따라 모터를 돌리고, 냉매를 회전시키고, 바람의 방향을 조절하고... -> 구체적인 구현부 (하위 클래스)
에어컨의 온도조절 모양이 있는 버튼을 그냥 떼서 모래사장에 놓고 누르면 모래사장이 차가워 지지 않는다.
버튼 (인터페이스)는 온도조절의 형식적인 모양(밑그림)이 있는 것 뿐이다.
추상메서드는 미완성 설계도(메서드에 바디를 생략하기 때문)이라고 보면, 인터페이스는 더 추상화 된 밑그림이다.
추상클래스는 추상메소드를 하나 이상 가진 클래스이며, 그냥 클래스와 별 차이 없어보이지만, (추상 메서드 이외에 다른거 다 넣어도 됨)
인터페이스는 기본적으로 추상 메서드와 상수만을 맴버로 가질 수 있기 때문에 추상클래스에 비해 추상화 정도가 더 높다!
인터페이스의 기본 구조
인터페이스를 선언하는것은 클래스를 작성하는 것과 비슷하지만, class 대신에 interface 키워드를 사용한다.
또한, 일반 클래스와 다르게 내부의 모든 필드가 public static final 로 정의되고, static, default 메서드 이외의 모든 메서드가 public abstract 로 정의된다.
코드예시
public interface InterfaceEx {
public static final int rock = 1; // 인터페이스 인스턴스 변수 정의
final int scissors = 2; // public static 생략
static int paper = 3; // public & final 생략
public abstract String getPlayingNum();
void call() //public abstract 생략
}
위의 코드를 보면, interface 키워드를 사용해아 인터페이스가 만들어지고, 구현부(바디)가 없는 추상메서드, 상수 만으로 구성되어 있는 것을 볼 수 있다.
인터페이스 안에서 상수를 정의하는 경우 -> public static final 로 정의
메서드를 정의하는 경우 -> public abstract 로 정의
하지만, 인터에피으 내에서 선언 할때 알아서 붙여주므로 일부, 전체를 생략해도 무방함
인터페이스 구현
위에서는 인터페이스를 정의한 것이고, 이제는 인터페이스를 구현 해야한다.
작성예시
class 클래스명 implements 인터페이스명 {
... // 인터페이스에 정의된 모든 추상메서드 구현
}
특정 인터페이스를 구현한 클래스는 해당 인터페이스 안의 모든 추상메서드를 구현해야한다.
- 어떤 클래스가 특정인터페이스를 구현한다는 것은 그 클래스에게 인터페이스의 추상 메서드를 반드시 구현하도록 강제하는 것이다.
- 어떤 클래스가 어떤 인터페이스를 구현한다는 것은 그 인터페이스가 가진 모든 추상 메서드들을 해당 클래스 내에서 오버라이딩하여 바디를 완성하는 것이다.
인터페이스의 다중 구현
JAVA에서 클래스는 다중 상속이 안된다.
그런데, 인터페이스는 다중구현이 된다!
정확히는 하나의 클래스가 여러개의 인터페이스를 구현 할 수 있다.
조건은 인터페이스는 인터페이스로부터만 상속이 가능하고, 클래스와 달리 최고 조상(Object 클래스)가 존재하지 않는다.
작성예시
class ExampleClass implements ExampleInterface1, ExampleInterface2, ExampleInterface3 {
... 생략 ...
}
interface Animal { // 인터페이스 선언. public abstract 생략 가능.
public abstract void cry();
}
interface Pet {
void play();
}
class Dog implements Animal, Pet { // Animal과 Pet 인터페이스 다중 구현
public void cry(){ // 메서드 오버라이딩
System.out.println("멍멍!");
}
public void play(){ // 메서드 오버라이딩
System.out.println("원반 던지기");
}
}
class Cat implements Animal, Pet { // Animal과 Pet 인터페이스 다중 구현
public void cry(){
System.out.println("야옹~!");
}
public void play(){
System.out.println("쥐 잡기");
}
}
public class MultiInheritance {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
dog.cry();
dog.play();
cat.cry();
cat.play();
}
}
// 출력값
멍멍!
원반 던지기
야옹~!
쥐 잡기
위의 코드를 보면 Dog, Cat 클래스에 Animal, Pet 인터페이스가 다중 구현 된 걸 볼 수 있다.
왜 클래스는 다중상속이 안되는데 얘는 되냐?
클래스가 다중상속이 안되는 이유 : 부모클래스에 동일한 이름의 변수 or 메서드가 있으면 충돌남
인터페이스는 에초에 미완성이기 때문에 그대그때 구현해야 해서 충돌 할 일이 없음.
번외로, 클래스를 선언하면서 인터페이스도 구현 할 수 있다.
abstract class Animal { // 추상 클래스
public abstract void cry();
}
interface Pet { // 인터페이스
public abstract void play();
}
class Dog extends Animal implements Pet { // Animal 클래스 상속 & Pet 인터페이스 구현
public void cry(){
System.out.println("멍멍!");
}
public void play(){
System.out.println("원반 던지기");
}
}
인터페이스의 장점
인터페이스는 다중상속이 되디때문에 갖는 장점이 있다.
일단 기존의 상위 클래스 - 하위 클래스 관계는 이러하다.

만약 이 상태에서 User에 의존하는 클래스가 하나 더 생기게 되엇을 때 , 변동사항이 생긴다면 클래스를 하나 더 만들어서 다시 User에 상속 시켜야 한다.
그리고, User에 해당 클래스의 매개변수나 메서드가 들어와야 한다면 그에 맞추어서 매개변수를 수정해야한다!
(User의 코드도 수정해야 한다!)
-> 코드가 늘어나고 불편하다!

User에 의존하는 클래스를 그냥 인터페이스로 연결하면 변동사항이 생겼으면 그냥 의존하는 클래스를 수정하면 그만이다.
이렇게 되면 User의 코드도 수정할 필요가 없어진다.
-> 코드변경이 최소화되고, 손쉽게 기능을 사용 가능
-> 클래스를 수정하지 않아도 되니, 클래스를 수정할때 다른 곳에 영향을 끼칠 확률이 줄어듦
'백엔드 > JAVA_이론공부' 카테고리의 다른 글
JAVA_제네릭 (0) | 2022.09.28 |
---|---|
JAVA_열거형 (0) | 2022.09.28 |
JAVA_ final 키워드 (0) | 2022.09.22 |
JAVA_추상화 , 추상 클래스, abstract 제어자 (0) | 2022.09.22 |
JAVA_다형성, instanceof 연산자 (1) | 2022.09.22 |