package ex_interface;
public class Ex1 {
public static void main(String[] args) {
/*
* 인터페이스
* - 추상클래스보다 강제성이 더 강하다
*
*/
Tv tv = new Tv();
tv.turnPower();
tv.tvStatus();
// 인터페이스는 인스턴스 생성(new) 불가능! = 추상클래스
// RemoteControl remote = new RemoteControl(); // 오류 발생!
// 인터페이스를 구현한 클래스가 존재하는 경우
// 일반적으로 인터페이스 타입으로 업캐스팅 후에
// 공통된 기능을 다형성으로 다루는 것이 보편적
// => Tv & Audio의 부모 인터페이스인 RemoteControl 타입 사용
// Tv -> RemoteControl 업캐스팅
RemoteControl remote = new Tv(); // 업캐스팅!
remote.turnPower();
remote.channelUp();
remote.channelDown();
remote.volumeUp();
remote.volumeDown();
remote.changeChannel(10);
// remote.tvStatus(); // 오류 발생! 자식 클래스에서 정의한 메서드는 호출 X
// Audio -> RemoteControl 업캐스팅
remote = new Audio(); // 업캐스팅!
remote.turnPower();
remote.channelUp();
remote.channelDown();
remote.volumeUp();
remote.volumeDown();
remote.changeChannel(10);
}
}
// RemoteControl 인터페이스를 구현하는 구현체 클래스 Tv를 정의
// => 클래스명 뒤에 implements 키워드를 쓰고 뒤에 인터페이스명을 지정
class Tv implements RemoteControl {
boolean isPowerOn = false;
// RemoteControl 인터페이스를 구현하기 위해 implements 할 경우
// 인터페이스 내의 모든 추상메서드를 구현(오버라이딩)해야한다!
@Override
public void turnPower() {
System.out.println("Tv 전원 상태 변경!");
isPowerOn = !isPowerOn;
}
@Override
public void channelUp() {
System.out.println("Tv 채널 증가!");
}
@Override
public void channelDown() {
System.out.println("Tv 채널 감소!");
}
@Override
public void changeChannel(int channel) {
System.out.println("Tv 채널 변경 - " + channel + " 번!");
}
@Override
public void volumeUp() {
System.out.println("Tv 볼륨 증가!");
}
@Override
public void volumeDown() {
System.out.println("Tv 볼륨 감소!");
}
public void tvStatus() {
System.out.println("전원 상태 : " + isPowerOn);
System.out.println("최소 채널 : " + MIN_CHANNEL);
System.out.println("최대 채널 : " + MAX_CHANNEL);
System.out.println("최소 볼륨 : " + MIN_VOLUME);
System.out.println("최대 볼륨 : " + MAX_VOLUME);
}
}
class Audio implements RemoteControl {
@Override
public void turnPower() {
System.out.println("Audio 전원 상태 변경!");
}
@Override
public void channelUp() {
System.out.println("Audio 채널 증가!");
}
@Override
public void channelDown() {
System.out.println("Audio 채널 감소!");
}
@Override
public void changeChannel(int channel) {
System.out.println("Audio 채널 변경 - " + channel + " 번!");
}
@Override
public void volumeUp() {
System.out.println("Audio 볼륨 증가!");
}
@Override
public void volumeDown() {
System.out.println("Audio 볼륨 감소!");
}
}
package ex_interface;
public class Ex2 {
public static void main(String[] args) {
/*
* 인터페이스
* - 다중 구현(implements)이 가능
*
*/
SubClass sc = new SubClass();
sc.method1(); // MyIntreface1의 추상메서드를 서브클래스에서 재정의한 메서드 호출
sc.method2(); // 서브클래스에서 재정의한 메서드 호출
// 인터페이스도 instaceof 연산자의 판별 대상이 될 수 있다!
// sc는 MyInterface1 입니까? true
if (sc instanceof MyInterface1) {
System.out.println("sc는 MyInterface1 입니다!");
} else {
System.out.println("sc는 MyInterface1이 아닙니다!");
}
// sc는 MyIntreface2 입니까? true
if (sc instanceof MyInterface2) {
System.out.println("sc는 MyIntreface2 입니다!");
} else {
System.out.println("sc는 MyInterface2가 아닙니다!");
}
// sc -> MyInterface1 타입으로 업캐스팅
MyInterface1 mi1 = sc;
mi1.method1(); // MyInterface1이 가진 추상메서드
mi1.method2();
// System.out.println(mi1.NUM1);
System.out.println(MyInterface1.NUM1); // MyInterface1 가진 상수
// System.out.println(MyInterface1.NUM2); // 오류 발생! MyInterface2 가진 상수
// sc -> MyInterface2 타입으로 업캐스팅
MyInterface2 mi2 = sc;
mi2.method2();
// mi2.method1(); // 오류 발생! MyIntreface1 가진 추상메서드
System.out.println(MyInterface2.NUM2);
// System.out.println(MyInterface2.NUM1); // 오류 발생!
}
}
interface MyInterface1 {
public int NUM1 = 10; // 상수
public void method1(); // 추상메서드
public void method2();
}
interface MyInterface2 {
public static final int NUM2 = 20; // 상수
public abstract void method2(); // 추상 메서드
}
// MyInterface1, MyInterface2 인터페이스를 구현하는 서브클래스 SubClass 정의
class SubClass implements MyInterface1, MyInterface2 {
// 부모 인터페이스로부터 상속받은 추상메서드 구현 필수!
@Override
public void method1() {
System.out.println("서브클래스에서 구현한 추상메서드 method1()");
}
@Override
public void method2() {
System.out.println("서브클래스에서 구현한 추상메서드 method2()");
}
}
package ex_interface;
public class Ex3 {
public static void main(String[] args) {
/*
* 인터페이스
* - 인터페이스끼리도 상속이 가능
*
*/
}
}
interface ParentInterface1 {
public abstract void parentMethod1();
}
interface ParentInterface2 {
public abstract void parentMehtod2();
}
// ChildInterface 인터페이스 정의 - ParentInterface1, ParentInterface2 상속
// 주의1. 인터페이스간의 상속은 extends 키워드 사용
// 주의2. 부모인터페이스를 상속받은 자식인터페이스에서 추상메서드 구현 없음!
// => 인터페이스 내에는 무조건 추상메서드만 존재해야하므로 구현 X
interface ChildInterface extends ParentInterface1, ParentInterface2 {
// 2개의 부모인터페이스를 상속받으면
// 부모인터페이스의 추상메서드와 자신의 추상메서드를 모두 갖게 됨
// 즉, parentMethod1(), parentMethod2() 추상메서드와
public abstract void childMethod3(); // 자신의 추상메서드를 갖데 됨!
}
// SubClass2 클래스 정의 - ChildInterface 인터페이스 구현
class SubClass2 implements ChildInterface {
@Override
public void parentMethod1() {
System.out.println("서브클래스에서 구현한 parentMethod1()");
}
@Override
public void parentMehtod2() {
System.out.println("서브클래스에서 구현한 parentMethod2()");
}
@Override
public void childMethod3() {
System.out.println("서브클래스에서 구현한 childMethod3()");
}
}
class ParentClass {
public void normalMethod() {
System.out.println("ParentClass의 normalMethod()");
}
}
// 하나의 서브클래스는 하나의 슈퍼클래스와 1개 이상의 인터페이스를 부모로 가질 수 있다.
// 주의! extends와 implements 동시 사용 시 extends를 먼저 선언해야함!
class SubClass3 extends ParentClass implements ParentInterface1, ParentInterface2 {
@Override
public void parentMethod1() {
// TODO Auto-generated method stub
}
@Override
public void parentMehtod2() {
// TODO Auto-generated method stub
}
}
package ex_interface;
// 인터페이스 정의
public interface RemoteControl {
/*
* 인터페이스
* < 정의 기본 문법 >
* [접근제한자] interface 인터페이스명 {
*
* // 상수 선언
* // 추상메서드 정의
*
* // 1.8 이후
* // 디폴트 메서드 정의
* // 정적 메서드 정의
*
* }
*/
// 상수
public static final int MAX_VOLUME = 100;
public static final int MIN_VOLUME = 0;
int MAX_CHANNEL = 100; // 상수(static final 생략되어 있음)
public int MIN_CHANNEL = 1; // 상수
// => 인터페이스 내의 모든 변수는 상수로 취급됨!
// 인터페이스 내의 모든 메서드는 추상메서드로 취급됨!
// public void turnPower() {} // 오류 발생!
public void turnPower(); // 추상메서드로 정의(abstract 생략되어 있음)
public abstract void channelUp(); // 추상메서드
public abstract void channelDown();
public abstract void changeChannel(int channel);
void volumeUp(); // 추상메서드(public abstract 생략되어 있음)
void volumeDown(); // 추상메서드
}