본문 바로가기

BackEnd/Java

[java] 인터페이스2

728x90
반응형

1. 다중 인터페이스

   ▷ 구현 객체는 여러 개의 인터페이스를 통해 구현 객체를 사용할 수 있습니다.

   ▷ 구현 클래스는 인터페이스 A와 인터페이스 B를 implements 뒤에 쉼표로 구분해서 작성합니다.

        이러면, 모든 인터페이스가 가진 추상 메소드를 재정의합니다.

   ▷ 여러개의 객체가 각각의 인터페이스를 통해 구현 객체를 불러오는 것입니다.

 

1. RemoteControl 인터페이스
public interface RemoteControl {
	void turnOn();
	void turnOff();
}​

 

2. Searchable 인터페이스
public interface Searchable {
	void search(String url);
}​

 

3. SmartTelevision 클래스
public class SmartTelevision implements RemoteControl, Searchable {
	@Override
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}
	
	@Override
	public void turnOff() {
		System.out.println("TV를 끕니다.");
	}
	
	@Override
	public void search(String url) {
		System.out.println(url + "을 검색합니다.");
	}
}​

 

4. MultiInterfaceImplExample 메인 클래스

public class MultiInterfaceImplExample {
	public static void main(String[] args) {
		// RemoteControl 인터페이스 변수 선언 및 구현 객체 대입
		RemoteControl rc = new SmartTelevision();
		
		rc.turnOn();
		rc.turnOff();
		
		// Searchable 인터페이스 변수 선언 및 구현 객체 대입
		Searchable searchable = new SmartTelevision();
		
		searchable.search("https://www.youtube.com");
	}
}

//	출력 : 
//	TV를 켭니다.
//	TV를 끕니다.
//	https://www.youtube.com을 검색합니다.

 

 

2. 인터페이스 상속

   ▷ 인터페이스도 다른 인터페이스를 상속할 수 있습니다. 다중 상속을 허용합니다.

   ▷ extens 키워드 뒤에 상속할 인터페이스들을 나열합니다.

   ▷ 자식 인터페이스의 구현 클래스는 자식 인터페이스의 메소드뿐만 아니라 부모 인터페이스의 모든 추상 메소드를 재정의합니다.

   ▷ 구현 객체는 다음과 같이 자식 및 부모 인터페이스 변수에 대입될 수 있습니다.

 

1. InterfaceA 인터페이스
public interface InterfaceA {
	void methodA();
}​

 

2. InterfaceB 인터페이스
public interface InterfaceB {
	void methodB();
}​

 

3. InterfaceC 인터페이스
public interface InterfaceC extends InterfaceA, InterfaceB {
	void methodC();
}​

 

4. InterfaceClmpl 인터페이스
public class InterfaceCImpl implements InterfaceC {
	public void methodA() {
		System.out.println("InterfaceCImpl-methodA() 실행");
	}
	
	public void methodB() {
		System.out.println("InterfaceCImpl-methodB() 실행");
	}
	
	public void methodC() {
		System.out.println("InterfaceCImpl-methodC() 실행");
	}
}​

 

5. ExtendsExample 인터페이스
package interface04;

public class ExtendsExample {
	public static void main(String[] args) {
		
		InterfaceCImpl impl = new InterfaceCImpl();
		
		InterfaceA ia = impl;
		ia.methodA();
//		ia.methodB();
		System.out.println();
		
		InterfaceB ib = impl;
//		ib.methodA();
		ib.methodB();
		System.out.println();
		
		InterfaceC ic = impl;
		ia.methodA();
		ib.methodB();
		ic.methodC();
		
//		실제 사용할 때는 아래와 같이 사용합니다.
//		impl.methodA
//		impl.methodB
//		impl.methodC
	}
}

//	출력 :
//	InterfaceCImpl-methodA() 실행
//	
//	InterfaceCImpl-methodB() 실행
//	
//	InterfaceCImpl-methodA() 실행
//	InterfaceCImpl-methodB() 실행
//	InterfaceCImpl-methodC() 실행

 

 

3. 타입 변환

◎ 자동 타입 변환

   ▷ 자동으로 타입 변환이 일어나는 것입니다.

   ▷ 부모 클래스가 인터페이스를 구현하고 있다면 자식 클래스도 인터페이스 타입으로 자동 타입 변환될 수 있습니다.

 

1. A 인터페이스
public interface A {
}​

 

2. B 클래스

public class B implements A {
}​

 

3. C 클래스
public class C implements A {
}​

 

4. D 클래스
public class D extends B {
}​

 

5. E 클래스
public class E extends C {
}​

 

6. PromotionExample 메인 클래스
public class PromotionExample {
	public static void main(String[] args) {
		// 구현 객체 생성
		B b = new B();
		C c = new C();
		D d = new D();
		E e = new E();
		
		// 인터페이스 변수 선언
		A a;
		
		// 변수에 구현 객체 대입
		a = b;	// A ← B (자동 타입 변환)
		a = c;	// A ← C (자동 타입 변환)
		a = d;	// A ← D (자동 타입 변환)
		a = e;	// A ← E (자동 타입 변환)
		
		// 구현 클래스 ← (구현 클래스)부모 인터페이스 : 강제 타입변환
	}
}​


오류 없이 모두 자동 타입 변환됩니다.

 

 

◎ 강제 타입 변환

   ▷ 캐스팅 기호를 사용해서 인터페이스 타입을 구현 클래스 타입으로 변환시키는 것입니다.

   ▷ 구현 객체가 인터페이스 타입으로 자동 변환되면, 인터페이스에 선언된 메소드만 사용 가능합니다.

 

1. Vehicle 인터페이스
public interface Vehicle {
	void run();
}​

 

2. Bus 클래스
public class Bus implements Vehicle {
	
	@Override
	public void run() {
		System.out.println("버스가 달립니다.");
	}
	
	public void checkFare() {
		System.out.println("승차요금을 체크합니다.");
	}
}​

 

3. CastingExample 메인 클래스
public class CastingExample {
	public static void main(String[] args) {
		Vehicle vehicle = new Bus();
		
		vehicle.run();
		
		Bus bus = (Bus) vehicle;
		bus.run();
		bus.checkFare();
	}
}

//	출력 : 
//	버스가 달립니다.
//	버스가 달립니다.
//	승차요금을 체크합니다.​

 

 

4. 다형성

   ▷ 사용 방법은 동일하지만 다양한 결과가 나오는 성질입니다.

   ▷ 인터페이스 역시 다형성을 구현하기 위해 재정의와 자동 타입 변환 기능을 이용합니다.

 

매개변수의 다형성

   ▷ 매개변수 타입을 인터페이스로 선언하면 메소드 호출시 다양한 구현 객체를 대입할 수 있습니다.

 

1. Vehicle 인터페이
public interface Vehicle {
	void run();
}​

2. Taxi 클래스
public class Taxi implements Vehicle {
	@Override
	public void run() {
		System.out.println("택시가 달립니다.");
	}
}​


3. Bus 클래스
public class Bus implements Vehicle {
	@Override
	public void run() {
		System.out.println("버스가 달립니다.");
	}
}​


4. Driver 클래스
public class Driver {
	void drive(Vehicle vehicle) {
		vehicle.run();
	}
}​


5. DriverExample 메인클래스
public class DriverExample {

	public static void main(String[] args) {
		Driver driver = new Driver();
		
		Bus bus = new Bus();
		Taxi taxi = new Taxi();
		
		driver.drive(bus);
		driver.drive(taxi);
	}
}

//	출력 :
//	버스가 달립니다.
//	택시가 달립니다.


 

 

 

5. instanceof 연산자

   ▷ 인터페이스에서도 객체 타입을 확인하기 위해 instanceof 연산자를 사용 가능합니다.

   ▷java12부터는 instanceof 연산의 결과가 true일 경우, 우측 타입 변수를 사용할 수 있기 때문에 강제 타입 변환이 필요 없습니다.

 

1. Vehicle 인터페이스
public interface Vehicle {
	void run();
}​


2. Bus 클래스
public class Bus implements Vehicle {
	@Override
	public void run() {
		System.out.println("버스가 달립니다.");
	}
	
	public void checkFare() {
		System.out.println("승차요금을 체크합니다.");
	}
}​


3. Taxi 클래스
public class Taxi implements Vehicle {
	@Override
	public void run() {
		System.out.println("택시가 달립니다.");
	}
}​


4. InstanceofExample 메인 클래스
public class InstanceofExample {
	public static void main(String[] args) {
		Taxi taxi = new Taxi();
		Bus bus = new Bus();
		
		ride(taxi);
		System.out.println();
		ride(bus);
	}
	
	public static void ride(Vehicle vehicle) {
		if(vehicle instanceof Bus) {
			Bus bus = (Bus) vehicle;
			bus.checkFare();
		}
		
		
		/* 
		 * Java12부터 사용가능합니다.
		if(vehicle instanceof Bus bus) {
			bus.checkFare();
		}
		*/
		vehicle.run();
	}
}

//	출력 : 
//	택시가 달립니다.
//
//	승차요금을 체크합니다.
//	버스가 달립니다.​


 

 

6. sealed 인터페이스

   ▷ Java15부터 무분별한 자식 인터페이스 생성을 방지하기 위해 봉인된 인터페이스 사용

public sealed interface InterfaceA permits InterfaceB { ... }

   ▷ sealed 키워드를 사용하면 permits 키워드 뒤에 상속 가능한 자식 인터페이스를 지정. non-sealed는 봉인을 해제한다는 뜻

public non-sealed interface InterfaceB extends InterfaceA { ... }

 

sealed는 일단 다룰 수 없기때문에 예제는 따로 작성하지 않았습니다.

여러가지 인터페이스를 또 다뤄보았는데 개념이 너무 어렵네요,,

 

다른 예제들을 더 살펴보면 할 수 있겠죠??

 

좀 더 힘내봅시다!!

 

많은 분들의 피드백은 언제나 환영합니다! 많은 댓글 부탁드려요~~

 

 

 

 

728x90
반응형