Java
에서는 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러 가지 문제가 발생할 수 있어 클래스를 통한 다중 상속은 지원하지 않는다.
하지만 다중 상속의 이점을 버릴 수 없어Java
에서는 인터페이스(Interface)라는 것을 통해 다중 상속을 지원하고 있다.
인터페이스(Interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미한다.
추상클래스(Abstract Class)는 추상 메소드 뿐만 아니라 생성자, 필드, 일반 메소드도 포함 할 수 있지만
인터페이스(Interface)는 오로지 추상 메소드와 상수만을 포함한다.
[public] interface 인터페이스이름 { ... }
public interface Predator { .... }
interface의 접근 제어자는 public
만 가능하다. interface는 class 설계도 이기 때문에 존재 목적이 애초에 공개이기 때문이다.
interface는 객체로 생성할 수 없기 때문에, 생성자를 가질 수 없다.
class Tiger extends Animal implements Predator{ ... }
class Lion extends Animal implements Predator{ ... }
위와 같이 implements
키워드를 사용한다.
인터페이스도 다른 인터페이스를 상속 할 수 있다.
클래스는 다중 상속을 허용하지 않지만, 인터페이스는 다중 상속을 허용한다.
public interface 하위인터페이스 extends 상위인터페이스1, 상위인터페이스2, ... { ... }
하위 인터페이스를 구현하는 구현 클래스에서는 하위 인터페이스의 추상 메소드와 상속하는 모든 상위 인터페이스의 추상메소드의 실체 메소드로 구현해야 한다.
하위인터페이스 변수 = new 구현클래스();
상위인터페이스1 변수 = new 구현클래스();
상위인터페이스2 변수 = new 구현클래스();
하위 인터페이스 변수는 하위인터페이스, 상위 인터페이스1, 상위 인터페이스2의 실체 메소드를 모두 사용할 수 있다.
상위 인터페이스1 변수는 상위 인터페이스1의 실체 메소드를 사용할 수 있다.
상위 인터페이스2 변수는 상위 인터페이스2의 실체 메소드를 사용할 수 있다.
default
메소드를 이용하면 인터페이스 내부에서 코드가 존재할 수 있다.default
메소드는 오버라이딩이 강제적이 아닌 선택적이라서 오버라이딩을 하지 않을시 기본 구현된 코드가 실행된다.default
키워드는 무조건 명시해야 한다.public interface Phone {
int version = 12;
String getManufacturer();
String getOS();
default void printRing(){
System.out.println("Sound : Ring Ring~~");
}
}
public class Galaxy implements Phone{
@Override
public String getManufacturer() {
return "Samsung";
}
@Override
public String getOS() {
return "Android";
}
@Override
public void printRing() {
System.out.println("Sound : Ring~~~~~~~");
}
}
static
메소드는 인스턴스 생성 없이 인터페이스 이름을 통해서 직접 메소드 호출이 가능하다.public interface Phone {
int version = 12;
String getManufacturer();
String getOS();
default void printRing(){
System.out.println("Sound : Ring Ring~~");
}
static void printUser(String user){
System.out.println("User : "+user);
}
}
public class Main {
public static void main(String[] args) {
Phone galaxy= new Galaxy();
Phone iphone = new IPhone();
System.out.println(galaxy.getManufacturer());
System.out.println(galaxy.getOS());
galaxy.printRing();
System.out.println();
System.out.println(iphone.getManufacturer());
System.out.println(iphone.getOS());
iphone.printRing();
// static 메소드 사용
Phone.printUser("Hong Gil Dong");
}
}
public interface Phone {
int version = 12;
String getManufacturer();
String getOS();
default void printRing(){
// private 메소드 사용
printInfo();
System.out.println("Sound : Ring Ring~~");
}
static void printUser(String user){
// static private 메소드 사용
getUser(user);
}
private void printInfo(){
System.out.println("Print Information");
}
private static void getUser(String user){
System.out.println("User : "+user);
}
}
public class Main {
public static void main(String[] args) {
Phone galaxy= new Galaxy();
Phone iphone = new IPhone();
System.out.println(galaxy.getManufacturer());
System.out.println(galaxy.getOS());
galaxy.printRing();
System.out.println();
System.out.println(iphone.getManufacturer());
System.out.println(iphone.getOS());
iphone.printRing();
Phone.printUser("Hong Gil Dong");
}
}
참고자료
https://limkydev.tistory.com/197
http://www.tcpschool.com/java/java_polymorphism_interface
https://wikidocs.net/217
https://interconnection.tistory.com/129
https://math-coding.tistory.com/169