본문 바로가기
JAVA

[JAVA] 인터페이스(특징, 형식과 구현), 상속과 인터페이스의 차이점

by 정공자씨 2024. 4. 22.

 

인터페이스

정의

  • 인터페이스는 구현 클래스(하위 클래스)가 준수해야 하는 메서드를 정의함
  • 인터페이스에서는 구현에 대한 세부 사항을 정하지 않고, 구현 클래스(하위 클래스)가 따라야 하는 계약을 지정함

 

인터페이스의 용도

  • 인터페이스를 구현하는 하위 클래스인터페이스에 선언된 추상 메서드(불완전한 메서드)들을 강제로 구현하게 하기 위해 사용
하위클래스에서 상위 클래스의 추상 메서드를 오버라이딩(@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