인터페이스는 상호작용을 위해서 미리 정의된 약속으로, 서로 다른 모듈이나 시스템을 연결하고 기능을 사용하기 위한 도움미 역할을 하는 것이다. 마치 컴퓨터를 키기 위해 전원을 누르는 것과 같은 것으로 여기서는 전원 버튼이
인터페이스
로서 컴퓨터를 켜는 역할을 한다. 실생활에서 무의식 가운데 쓰는 것들이 인터페이스
- 예를 들어 A라는 함수라는 호출하면 B라는 결과 도출되는 것이
인터페이스
다. 즉, 컴퓨터의 파워 전원 버튼, 변기의 레버 등이 인터페이스가 될 수 있다.- 즉, 인터페이스란 서로 다른 시스템이나 기능을 연결하여 사용할 수 있게 도와준다.
- 인터페이스는 인터페이스를 구현하는 모든 클래스에 대해 특정한 메소드가 반드시 존재하도록 강제한다.
API
가 되는 것이고 이 중간에 있는 것들은 뭐든지 인터페이스
EX.
키보드를 IOS 앱에 줌 ⇒ 규칙을 정해줌 이 키는 업로드 ⇒ 이렇게 되면 키의 입력을 받으면 백엔드 데이터베이스나 서버에 가서 알려줌
구현 객체가 같은 동작을 한다는 것을 보장
하는 것이다.가질 수 없다.
오직 추상 메소드와 상수만 멤버로 가질 수 있으며, 그 외의 요소는 허용하지 않는다.interface PlayCard {
public static final int NUMBER = 4;
final int DIAMOND = 3;
static int HEART = 2;
int CLOVER = 1;
// 위의 상수는 모두 public static final이며, 생략된 형태이다.
public abstract int getCardNumber();
String getCardKind();
// public 생략.
default void getNewCard() {
}
// public 생략.
static void staticMethod() {
}
}
예를 들어… 1초에 벨을 3번 눌러야만 반응하는 호출벨이라던지는 안좋다.. 결국 이런 것이 코드에 적용되면 안 좋은데 특정 순서대로 호출해야만 동작하는 함수라든지 우리가 아는 특정 값을 파라미터로 넘겨야만 동작하는 함수라든지는 안 좋다… ⇒ 주석이 면죄가 되지 않는다.. 즉 클린 코드의 중요성
호출벨을 누르면 직원이 오는 것 처럼, 함수도 마찬가지로 호출하면 결과가 뭔가 리턴된다라고 되는 것이 좋은 인터페이스
예외 상황
에 대한 처리 언제까지 어떤 결과가 오든, 에러가 리턴이 돼서 사용자가 알게 해야한다.음식점을 예시로 들자면, 음식점에 갔는데
저기요
라고 부르는데 직원이 자신을 보고 있음에도 오지 않았고 여러번 부르니벨
을 눌러야지 가죠라고 얘기를 한다면…저기요
는 구버전 인터페이스임에도 기분 나빠서 가지 않게 됨… 즉, 둘 다 지원하는 것이 맞음
- 신버전 인터페이스가 있음에도 구버전 인터페이스를 지원하는 것
⇒ MS가 잘해서 운영체제 독점하는 이유 : 이전 OS에서 돌아가는 프로그램들이 웬만하면 신 OS에서 다 돌아간다.
다중 상속, 즉 여러 개의 인터페이스로부터 상속 받는 것이 가능
하다.interface Movable {
void move(int x, int y);
}
interface Attackable {
void attack(Unit n);
}
interface Fightable implements Movable, Attackable {
}
abstract class Fighter implements Fightable {
public void move(int x, int y){
...
}
}
만약 모든 추상 메소드의 구현을 원하지 않는다면 위의 코드처럼 Fighter 클래스를 abstract
키워드를 붙여 추상 클래스로 선언해야 한다.
위에서는 move() 함수만을 구현했다. attack()을 구현하지 않았기 때문에 abstract Fighter인 추상 클래스로 선언을 했다.
자바에서는 상속과 구현을 동시에 할 수 있다.
class Fighter extends Unit implements Fightable {
public void move(int x, int y) { ... }
public void attack(Unit u) { ... }
}
class Animal {
public void cry(){
System.out.println("짖기!");
}
}
class Cat extends Animal {
@Override
public void cry(){
System.out.println("냐옹냐옹!");
}
}
class Dog extends Animal{
@Override
public void cry(){
System.out.println("멍멍!");
}
}
class MyPet extends Cat, Dog { ... }
// 1.
public class Test {
public static void main(String[] args){
MyPet pet = new MyPet();
pet.cry();
// 2.
}
}
다중 상속을 허용할 경우, 발생할 수 있는 문제는 메소드 출처의 모호성이다.
주석을 달아놓은 2에서 MyPet 클래스의 인스턴스인 pet이 cry() 메소드를 호출하면 이 메소드가 Dog 클래스의 cry() 메소드인지, Cat 클래스의 cry() 메소드인지 구분할 수 없는 모호성
이 생긴다.
이와 같은 이유로 자바에서 다중 상속을 지원하지 않는다.
하지만, 인터페이스를 이용해 다중 구현을 하게되면 위와 같은 메소드 호출의 모호성을 방지할 수 있다.
interface Animal {
void cry();
}
interface Cat extends Animal {
void cry();
}
interface Dog extends Animal {
void cry();
}
class Pet implements Cat, Dog {
@Override
public void cry(){
System.out.println("멍멍~ 냐옹냐옹~")
}
}
public class Test{
public static void main(String[] args){
Pet pet = new Pet();
pet.cry();
}
}
// 결과
멍멍~ 냐옹냐옹~
Cat, Dog 인터페이스를 동시에 구현한 Pet 클래스에서만 cry() 메소드를 정의하므로, 앞의 예제에서 발생한 메소드 호출의 모호성이 없다.
자손 클래스의 인스턴스를 조상 타입의 참조 변수로 참조하는 것이 가능하다.
인터페이스도 인터페이스를 구현한 클래스의 조상이라고 할 수 있으므로, 해당 인터페이스 타입의 참조 변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있다.
메소드의 동작은 구현
하는 자식 클래스로 위임한다. 공유의 목적을 갖는다.인터페이스와 추상 클래스 모두 객체지향 프로그래밍(OOP)의 원칙을 따르며, 코드의 재사용성과 유지보수성을 향상시키는 데 기여한다.