🤔 인터페이스를 왜 사용해야할까?
하나의 객체가 아니라 여러 객체들과 사용이 가능하므로 어떤 객체를 사용하느냐에 따라서 실행 내용과 리턴값이 달라질 수 있어서! ➡️ 다양화
public interface 인터페이스이름 { }
public static final
특성 가짐public abstract
가 자동으로 붙음public interface RemoteControl {
//상수
int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
//추상 메소드
void turnOn();
void turnOff();
void setVolume(int volume);
}
implements
public class 구현클래스이름 implements 인터페이스이름 {
// 인터페이스에서 선언했던 추상 메소드, 실제 메소드 선언
}
public class 구현클래스이름 implements 인터페이스이름_1, 인터페이스이름_2 {
// 인터페이스_1 에서 선언했던 추상 메소드, 실제 메소드 선언
// 인터페이스_2 에서 선언했던 추상 메소드, 실제 메소드 선언
}
public interface RemoteControl {
//상수
int MAX_VOLUME = 10;
int MIN_VOLUME = 0;
//추상 메소드
void turnOn();
void turnOff();
void setVolume(int volume);
}
public class MyClass {
// 필드
RemoteControl rc = new Television();
// 생성자
MyClass() {
}
MyClass(RemoteControl rc) {
this.rc = rc;
rc.turnOn();
rc.setVolume(5);
}
// 메소드
void methodA() {
RemoteControl rc = new Audio();
rc.turnOn();
rc.setVolume(5);
}
void methodB(RemoteControl rc) {
rc.turnOn();
rc.setVolume(5);
}
}
public class MyClassExample {
public static void main(String[] args) {
System.out.println("1)----------------");
MyClass myClass1 = new MyClass();
myClass1.rc.turnOn();
myClass1.rc.setVolume(5);
System.out.println("2)----------------");
/* ⭐️ 인터페이스 변수에 객체 대입하기!!
* RemoteControl를 implements한 Audio 클래스
* MyClass의 생성자를 살펴보면
MyClass(RemoteControl rc) {
this.rc = rc;
rc.turnOn();
rc.setVolume(5);
} 라는 생성자가 존재하는데 Audio를 인터페이스 변수에 대입하며,
Audio 클래스에서 작성했던 함수를 사용할 수 있다.
-> 원하는 클래스를 넣으면서 값의 다양화가 가능해진다
*/
MyClass myClass2 = new MyClass(new Audio());
System.out.println("3)----------------");
MyClass myClass3 = new MyClass();
myClass3.methodA();
System.out.println("4)----------------");
MyClass myClass4 = new MyClass();
myClass4.methodB(new Television());
}
}
인터페이스 변수 = 구현 객체;
➡️ 구현 객체가 인터페이스 변수로 자동 타입 변환!🤔 자동 타입 변환이 필요한 이유가 무엇일까?
필드의 다형성과 매개 변수의 다형성을 구현할 수 있다.
public class Car {
// 인터페이스 타입 필드 선언과 초기 구현 객체 대입
Tire frontLeftTire = new HankookTire();
Tire frontRightTire = new HankookTire();
Tire backLeftTire = new HankookTire();
Tire backRightTire = new HankookTire();
void run() {
frontLeftTire.roll();
frontRightTire.roll();
backLeftTire.roll();
backRightTire.roll();
}
}
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.run();
myCar.frontLeftTire = new KumhoTire();
myCar.frontRightTire = new KumhoTire();
myCar.run();
}
}
public interface Vehicle {
public void run();
}
public class Driver {
public void drive(Vehicle vehicle) {
vehicle.run();
}
}
여기서 Bus() 라는 구현 클래스가 있다고 하자. Driver driver = new Driver();
Bus bus = new Bus();
driver.drive(bus); // -> 자동 타입 변환 발생!!
매개 변수의 타입 → 인터페이스일 경우 어떠한 구현 객체도 매개값으로 사용 OClassCaseException
→ 무작정 강제 타입 변환할 경우 생기는 예외 처리중첩 클래스 구조를 이용하기!
public class Car {
class Tire { } // 인스턴스 멤버 클래스
static class Engine { } // 정적 멤버 클래스
}
public class NestedClassExample {
public static void main(String[] arg) {
Car myCar = new Car();
Car.Tire tire = myCar.new Tire(); // 여기 채우기!
Car.Engine engine = new Car.Engine(); // 여기 채우기!
}
}
class Tire
→ 인스턴스 멤버 클래스static
이 붙지 않음Tire
객체를 만들기 전에 반드시 Car
객체가 먼저 있어야 한다!!static class Engine
→ 정적 멤버 클래스static
이 붙음Car
객체와 독립적으로 존재 가능Car
인스턴스를 만들 필요 ❌ myCar
가 있어야만 객체 생성 가능