개발/Java

[Java] Interface

yun000 2024. 12. 4. 18:50

<Virtual vs Abstract vs Interface>

Virtual = overriding이 필수아님, 완벽한 기능 제공. 타입을 동적으로 할당할 수 있다.

Abstract = 상속 oberriding 필수. 공통된 정의 제공. 완전하지 않음. 

Interface = overriding 필수. 다른 타입에 같은 기능 추가하고 싶을 때. 다중 상속 가능.

사용 방법을 정의하고 통일.

<Interface>

사용 방법을 정의하고 통일하는 것

구현 필수. 인터페이스만으로는 객체를 만들 수 없다.

 

1. 인터페이스 선언

public interface RemoteControl
{
	public static final MAX_VOLUME=100;
        public static final MIN_VOLUME=0;
        public abstract void turnOn();
        void turnOff();
}

 

- 추상 메서드로도 작성 가능 하지만 굳이 그렇게 안함. 자동으로 붙는다.

- 접근제한자는 class와 마찬가지로 public, default 둘 중 하나 사용

- 인터페이스는 필드에 상수는 있어도 변수는 없다.

→ 인터페이스만으로 객체를 만들 수 없기 때문에 데이터를 수정할 수 없으니 변수 넣을 수 없다.

상수는 쓸 수 있는데 그 이유는 어차피 변하거나 수정할 수 없기 때문이다.

 

2. 구현 클래스 선언

구현=인터페이스로 사용할 수 있게 하겠다

구현 클래스에서 추상 메소드 재정의할 때 더 낮은 접근 제한자로 재정의할 수 없다.

상위 메소드 접근제한자가 public이라면 재정의할 때 private으로 바꿀 수 없다는 의미.

 

ex) 리모콘 인터페이스를 구현한 TV와 오디오 객체는

TV와 오디오를 remoteControl로 사용 가능하게끔 만들겠다는 의미

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

 

3. 변수 선언과 구현 객체 대입

RemoteControl rc;
rc=new TV();
rc.turnOn();
rc=new Audio();
rc.turnOn();

-->
TV를 켰습니다
오디오를 켰습니다

<다중 인터페이스>

구현 객체는 여러개의 인터페이스 implements할 수 있다.

이 경우 모든 인터페이스의 추상 메소드 재정의해야한다.

public interface RemoteControl{ void turnOn(); void turnOff(); }
public interface Searchable{ void search(String url); }

public class SmartTV implemens RemoteControl,Searchable{...}
RemoteControl rc=new SmartTV();
rc.turnOn();
rc.turnOff();
Searchable sa=new SmartTV();
sa.search("https://yun000.tistory.com/");

 

<타입 변환>

1. 자동 타입 변환

부모 클래스가 인터페이스 구현시

자식 클래스도 인터페이스 타입으로 자동 타입 변환될 수 있다.

public interface A { }
public class B implements A { }

B b=new B();
A a;
a=b; //가능

 

2. 강제 타입 변환

캐스팅 기호를 사용해서

인터페이스 타입을 구현 클래스 타입으로 변환시키는 것

public interface Vehicle{ void run(); }
public class Bus implements Vehicle
{
	@Override
        public void run{ System.out.println("버스 달림"); }
}


Vehicle vehicle=new Bus();
vehicle.run();
//강제 타입 변환
Bus bus=(Bus)vehicle;
bue.run();
bus.checkFare();

 

<다형성>

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

 

1. 필드의 다형성

부모 타입이 인터페이스일 때 다형성

public interface Tire{ void roll(); }
public class HankookTire implements Tire
{
	@Override
    	publi void roll(){ System.out.println("한국 타이어 roll");}
}
public class KumhoTire implements Tire
{
	@Override
    	public void roll(){ System.out.println("금호 타이어 roll");}
}
pucblic class Car
{
	Tire tire1=new HankookTire();
        Tire tire2=new HankookTire();
        void run(){tire1.roll(); tire2.roll();}
}
public clss CarExample
{
	public static void main(String[] args)
    {
    	Car myCar=new Car();
        myCar.run();
        myCar.tire1=new KumhoTire();
        myCar.tire2=new KumhoTire();
        myCar.run();
    }
}

-->
한국 타이어 roll
한국 타이어 roll
금호 타이어 roll
금호 타이어 roll

 

2. 매개변수의 다형성

매개값으로 어떤 값을 주느냐에 따라 메소드의 실행결과가 다르게 나오는 것

public interface Vehicle{ void run(); }
public class Dirver{ void drive(Vehicle vehicle) { vehicle.run(); }
public class Bus implements Vehicle
{
	@Override
    	public void run(){System.our.println("버스 달림");}
}
public class Taxi implements Vehicle
{
	@Override
    	public void run(){System.out.println("택시 달림");}
}
Driver driver=new Driver();

Bus bus=new Bus();
Taxi taxi=new Taxi();

driver.drive(bus);
driver.drive(taxi);

-->
버스 달림
택시 달림

 

<객체 타입 확인>

instanceof를 여기서도 사용해서 객체 타입을 확인할 수 있다.

if(vehicle instanceof Bus bus)
{ bus.checkFare(); }

 

 

8.10, 8.11, 8.12