백엔드 수업 #08 인터페이스 - 03 인터페이스 구현

sookyoung.k·2022년 12월 7일
0
post-thumbnail

개발 코드가 인터페이스 메소드를 호출하면 인터페이스는 객체의 메소드를 호출한다. 이 때 객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개 타입, 리턴 타입을 가진 실체 메소드를 가지고 있어야 한다! 이러한 객체를 인터페이스의 구현 (implement) 객체라고 하며, 구현 객체를 생성하는 클래스를 구현 클래스라고 한다.

구현 클래스

클래스 선언부에 implements 키워드 추가하고 인터페이스 명을 명시한다!

public class Television implements RemoteControl {
	// 필드
	private int volume;
	

	// ★인터페이스에 정의된 추상메소드는 반드시 구현을 해줘야 한다. 
	@Override
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("TV를 끕니다.");
	}
	
    // setVolume() 추상 메소드의 실체 메소드 
    // 인터페이스 상수를 이용해서 volume 필드 값을 제한하고 있음 
	@Override
	public void setVolume(int volume) {
		if (volume > RemoteControl.MAX_VOLUME) {
			this.volume = RemoteControl.MAX_VOLUME;
		} else if (volume < RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 TV 볼륨: " + this.volume);
	}
	
}

public class Audio implements RemoteControl {
	// 객체지향 == 생산성! 부품 갈아끼우기!

	// 필드
	private int volume;
	
	@Override
	public void turnOn() {
		System.out.println("오디오를 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("오디오를 끕니다.");
	}

	@Override
	public void setVolume(int volume) {
		if (volume > RemoteControl.MAX_VOLUME) {
			this.volume = RemoteControl.MAX_VOLUME;
		} else if (volume < RemoteControl.MIN_VOLUME) {
			this.volume = RemoteControl.MIN_VOLUME;
		} else {
			this.volume = volume;
		}
		System.out.println("현재 오디오 볼륨: " + this.volume);
	}

구현 클래스가 작성되면 new연산자로 객체를 생성할 수 있다!

인터페이스로 구현 객체를 사용하려면 인터페이스 변수를 선언하고 구현 객체를 대입해야 한다!

인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입될 때 구현 객체의 번지를 저장한다.

public static void main(String[] args) {
		// 객체를 생성한 다음 넣어주세욧. 
		RemoteControl rc1 = new Television(); // 인터페이스를 할 때는 처음부터 사용할 때 자동형변환을 해서 쓰세욧. 
		// 바로 실행!! 
		rc1.turnOn(); // (RemoteControl이 부모고 자동형변환을 함. 그리고 turnOn을 호출합니다.
        // 다형성과 원리가 아주 똑같습니다!!! 이름이 인터페이스고 추상메소드가 추가된 것이 다를 뿐
		
		RemoteControl rc2 = new Audio();
		rc2.turnOn();
		// 이렇게도 해줄 수 있지만... 인터페이스는 아래처럼 더 효율적으로 할 수 있다!!! 
		
		
		RemoteControl rc;
		rc3 = new Television();
		rc3.turnOn();
		rc3.setVolume(5);
		rc3.turnOff();
		
		rc4 = new Audio(); // rc를 new Audio()로 바꿔 끼웠다! 오! 더 편하다! (같이 상속을 받고 있기 때문에 교체가 당연한 거임. 당연함.) 
		rc4.turnOn();
		rc4.setVolume (5);
		rc4.turnOff();
}

[출력 결과]
TV를 켭니다.
오디오를 켭니다.
TV를 켭니다.
현재 TV 볼륨: 5
TV를 끕니다.
오디오를 켭니다.
현재 오디오 볼륨: 5
오디오를 끕니다

익명 구현 객체

일회성의 구현 객체를 만들기 위해서 클래스를 선언하는 것은 비효율적인 일이다. 익명 구현 객체는 소스 파일을 만들지 않고도 구현 객체를 만들 수 있게 해주는 것!!!

만드는 방법!! 대 공 개 (이거 복습 안 해둬서 뒤에가서 람다식 배울 때 아주 헷갈렸다. 꼭 잘 복습하고 가야 하는 부분이다.)

인터페이스 변수 = new 인터페이스() {
	//인터페이스에 선언된 추상 메소드의 실체 메소드 선언 
};

작성 시 주의할 것은... 세미콜론(;)을 반드시 붙여야 한다는 점. (왜냐면 이것도 하나의 실행문이기 때문에)

원래 new연산자 뒤에는 클래스 이름이 와야 하지만 없다! 인터페이스 () {} 는 인터페이스를 구현해서 중괄호{}와 같이 클래스를 선언하라는 뜻이다. new 연산자는 이렇게 선언된 클래스를 객체로 생성한다.

중괄호{}에는 인터페이스에 선언된 모든 추상 메소드들의 실체 메소드를 작성해야 한다!

public class RemoteControlEx{
	public static void main(String[] args) {
		RemoteControl rc = new Remote() {
        	public void turnOn() { 실행문 }
            public void turnOff() { 실행문 }
            public void setVolume(int volume) { 실행문 }
        }
    }			
}

다중 인터페이스 구현 클래스

객체는 다수의 인터페이스 타입으로 사용할 수 있다! 클래스 상속은 하나만 가능하지만 인터페이스 상속은 여러개 가능하다는 사실~!! 인터페이스 짱짱맨~~~

다중 인터페이스를 작성할 경우, 모든 인터페이스의 추상 메소드에 대해서 실체 메소드를 작성해야 한다.

public interface Searchabel {
	// 추상메소드
	void search(String url);
}

public interface RemoteControl2 {
	// 추상 메소드
	void turnOn();
	void turnOff();
}


public class SmartTelevision implements RemoteControl2, Searchabel { // 인터페이스 특징: 두 개를 동시 상속 (다중 상속: 부모가 둘이 되는 거 ㅋㅋㅋ) (그냥 웃어봄)
	
	@Override
	public void search(String url) {
		System.out.println(url + "을 검색합니다.");
	}

	@Override
	public void turnOn() {
		System.out.println("TV를 켭니다.");
	}

	@Override
	public void turnOff() {
		System.out.println("TV를 끕니다.");
	} 
	
}
profile
영차영차 😎

0개의 댓글