인터페이스
정의
- 인터페이스는 구현 클래스(하위 클래스)가 준수해야 하는 메서드를 정의함
- 인터페이스에서는 구현에 대한 세부 사항을 정하지 않고, 구현 클래스(하위 클래스)가 따라야 하는 계약을 지정함
인터페이스의 용도
- 인터페이스를 구현하는 하위 클래스가 인터페이스에 선언된 추상 메서드(불완전한 메서드)들을 강제로 구현하게 하기 위해 사용
하위클래스에서 상위 클래스의 추상 메서드를 오버라이딩(@Override)하여 구현하도록 강제함
인터페이스의 특징
1. 추상 클래스가 발전된 개념이므로, 인스턴스 생성(new 연산자로 생성)이 불가함
- 인터페이스 내에는 생성자가 없기 때문에(상수와 추상메서드만 있음)
- new 연산자를 사용하여 인스턴스 생성이 불가함
2. 인퍼페이스의 멤버로는 상수와 추상 메서드만 허용
3. 인터페이스와 하위 클래스의 관계는 구현(implements) 관계임
- 즉, 하위 클래스는 인터페이스를 구현해야 함
- 인터페이스 내의 추상 메서드를 하위 클래스에서 구현해야 함
4. 1개의 하위 클래스(구현 클래스)에서는 여러 개의 인터페이스를 구현할 수 있음(다중 상속)
public interface Animal {
}
public interface Pet {
}
public class Cat implements Animal, Pet { // 다중으로 상속 가능
}
5. 업캐스팅 시에 인터페이스 타입의 참조변수로 사용할 수 있음
- 인터페이스는 구현 클래스의 인스턴스를 받는 업캐스팅 참조변수로 사용
인터페이스 형식
public interface 인터페이스이름 {
상수;
추상메서드;
}
public interface Car {
public static final int SAFE_SPEED = 60; // 상수 선언
String LAW = "교통법규"; // 변수 선언하면, public static final 자동 추가
public abstract void speedUp();
public abstract void speedDown();
void stop(); // 인터페이스 내에서 추상메서드 선언시, public abstract 생략 가능
}
1. interface 키워드 뒤에 인터페이스 이름을 선언
- 클래스를 선언하는 것처럼 사용( class Car { } )
- 인터페이스 선언( interface Car { } )
2. 인터페이스 내에는 상수와 추상메서드로 구성
3. 인터페이스 내 추상메서드 선언시, public abstract 생략 가능
- 추상메서드는 선언부만 있고
- 구현부가 없음. 즉 { } 가 없음
4. 인터페이스 내 상수 선언시, public static final생략 가능
[ 컴파일 시에 추가 되어 생략 가능 ]
상수 선언 시 : public static final 생략 가능
추상 메서드 선언 시 : public abstract 생략 가능
5. 인터페이스 내에서 변수를 선언하면, 상수로 인식
- int SAFE_SPPED; 변수를 선언하면
- public static final가 자동으로 추가됨
인터페이스 구현
public class Cat implements Animal { // implements 키워드 사용
}
public class Cat implements Animal, Pet { // 쉼표(,)를 사용하여 다중 구현
}
- 인터페이스를 구현하는 클래스(하위 클래스)는 implements 키워드를 사용
- 하위 클래스는 쉼표로 구분된 여러 인터페이스를 구현할 수 있음(다중 상속)
인터페이스 내의 상수에 접근하는 방법
인터페이스명.상수명
Car.SAFE_SPEED Car.LAW
예제 : 인터페이스 구현하기
Car 인터페이스
public interface Car {
public static final int SAFE_SPEED = 60; // 상수 선언
public abstract void speedUp();
public abstract void speedDown();
public void stop(); // 인터페이스 내에서 추상메서드 선언시, abstract 생략 가능
}
Truck 클래스 : Car 인터페이스의 모든 기능을 구현(추상메서드를 구현)
public class Truck implements Car {
@Override
public void speedUp() {
System.out.println("트럭이 속도를 높입니다");
}
@Override
public void speedDown() {
System.out.println("트럭이 속도를 낮춥니다");
}
@Override
public void stop() {
System.out.println("트럭이 정지합니다");
}
}
SportCar 클래스 : Car 인터페이스의 추상메서드를 구현 + 자신만의 기능을 추가할 수 있음
public class SportCar implements Car {
@Override
public void speedUp() {
System.out.println("스포츠카가 속도를 높입니다");
}
@Override
public void speedDown() {
System.out.println("스포츠카가 속도를 낮춥니다");
}
@Override
public void stop() {
System.out.println("스포츠카가 정지합니다");
}
public void truboEngine() { // SportCar 클래스만 가진 기능 추가
System.out.println("스포츠카가 가진 고속 질주 기능입니다");
}
}
인터페이스 타입의 참조변수를 이용하여 업캐스팅으로 많이 사용
- 업캐스팅 시에, 참조변수는 인터페이스 부분을 가리킴
- 업캐스팅의 참조변수로 메서드 호출 시, 하위클래스에서 오버라이딩 된 메서드를 출력함
구현 클래스(하위 클래스)에서만 정의되어 있는 메서드는 다운 캐스팅하여 접근할 수 있음
public class CarTest {
public static void main(String[] args) {
// Car c1 = new Car(); // 인터페이스는 객체 생성 불가능
// Car.SAFE_SPEED = 1; // 상수의 값 변경 불가능
Car car1 = new SportCar(); // 인터페이스 타입은 업캐스팅으로 사용 가능
Car car2 = new Truck();
System.out.println(Car.SAFE_SPEED); // 60, 인터페이스명.상수명
// 오버라이딩된 메서드 출력
car1.speedDown(); // 스포츠카가 속도를 낮춥니다
car2.speedDown(); // 트럭이 속도를 낮춥니다
// SportCar 클래스에만 있는 truboEngine 메서드 출력
// car1.truboEngine(); //출력 불가, 인터페이스 타입으로 업캐스팅 되었기 때문
// SportCar 클래스에만 있는 메서드 출력 - 다운 캐스팅 필요
SportCar c = (SportCar)car1;
c.truboEngine(); // 스포츠카가 가진 고속 질주 기능입니다
}
}
예제
public class Driver {
private Car car; // 인터페이스 타입의 참조변수가 필드로 사용
public Driver {}; // 기본 생성자
// 생성자의 매개변수로 인터페이스 타입의 참조변수로 업캐스팅
// Car car = new SportCar();
// Car car = new Truck();
public Driver(Car car) {
this.car = car;
}
public void drive() {
car.speedDown();
car.speedUp();
car.stop();
}
public void speedUP(Car car) { // 메서드의 매개변수에서 업캐스팅으로 사용
if(car instanceof Truck) {
Truck truck = (Truck)car;
truck.speedUp();
}
else if(car instanceof SportCar) {
SportCar sportcar = (SportCar)car;
sportcar.speedUp();
}
}
}
public class CarTest {
public static void main(String[] args) {
// Car car = new Truck(); 업캐스팅
Driver driver = new Driver(new Truck());
driver.drive(); // truck 클래스의 (오버라이드 된) drive 메서드 실행
}
}
public class CarTest {
public static void main(String[] args) {
// Car car = new SportCar(); 업캐스팅
Driver driver2 = new Driver(new SportCar());
driver2.drive(); // SportCar 클래스의 (오버라이드 된) drive 메서드 실행
}
}
public class CarTest {
public static void main(String[] args) {
Driver driver = new Driver();
// Car car = new SportCar(); 업캐스팅
driver.speedUP(new SportCar());
// speedUp 메서드 내에서, 다운캐스팅을 진행하여
// Sportcar 클래스에만 있는 메서드를 호출함
}
}
상속와 인터페이스의 차이점
상속 | 인터페이스 |
extends 키워드 사용 | implements 키워드 사용 |
멤벼변수, 메서드(구현메서드) | 상수, 추상메서드 |
public static final int num; - 상수 public abstract void method(); - 추상메서드 |
|
public static final public abstract (생략 가능, 컴파일 시에 추가) |
|
단일 상속 (하위 클래스는 상위 클래스 1개만 상속 가능) |
다중 구현이 가능 (하위 클래스가 여러 인터페이스를 구현할 수 있음) |
추상메서드를 반드시 오버라이딩 하여 구현 | |
인터페이스끼리 상속이 가능 | |
Cat extends Animal | Cat implements Animal |
Cat implements Animal, Pet (다중 구현) |
상속과 인터페이스의 관계
출처
https://coding-factory.tistory.com/867
'JAVA' 카테고리의 다른 글
[JAVA] 상속과 인터페이스, 추상클래스와 인터페이스의 차이 (0) | 2024.04.23 |
---|---|
[JAVA] 추상 클래스, 추상 메서드, 추상클래스와 인터페이스 차이점 (0) | 2024.04.22 |
[JAVA] static 멤버(static 필드, static 메서드) (0) | 2024.04.22 |
[JAVA] final 지정자(클래스, 메서드, 변수에 지정하기) (0) | 2024.04.22 |
[JAVA] 싱글톤 패턴(만드는 방법, 사용하는 이유, 장단점) (0) | 2024.04.22 |