케네스로그

[Java] 인터페이스 본문

Dev/Java

[Java] 인터페이스

kenasdev 2022. 2. 20. 15:34
반응형

인터페이스 정의

인터페이스는 구현체에 대한 기능을 보증(약속)하기 위한 장치라고 할 수 있다. 인터페이스를 구현하는 클래스는 여러개의 인터페이스를 함께 구현할 수 있으며, 구현하기 위해 implements 키워드를 사용한다. 이는 abstract class를 구현하기위해 상속(extends)받는 것과 유사하다.

인터페이스는 body부분이 생략된 추상화 클래스의 집합이다. 따라서, 오직 메소드의 시그니처와 필드만 지닌다.

  • 메소드는 정의되지 않는다
  • 정적 변수처럼 필드를 정의하고 접근할 수 있다.

 

interface Computer {
    public void playGame(String gameName);
    public void searchGoogle(String keyword);
}

interface Phone {
    public void sendMessage(String content);
    public void makePhoneCall(String number);
}

인터페이스는 구현체 가져야할 공통적인 기능들을 정의한다. Computer는 게임기능, 구글링기능이 있다. Phone은 문자보내기, 전화걸기 기능이 있다.

그렇다면 SmartPhone은 이 두가지 기능이 모두 가능하다. 이것을 구현하면 다음과 같을 수 있다.

 

 

 

abstract class SmartPhone implements Computer, Phone {

    public String model;
    
    public SmartPhone(String model) {
        this.model = model;
    }
    
    @Override
    public void playGame(String gameName) {}

    @Override
    public void searchGoogle(String keyword) {}

    @Override
    public void sendMessage(String content) {}

    @Override
    public void makePhoneCall(String number) {}
}

SmartPhone은 Computer 인터페이스와 Phone 인터페이스 둘을 구현한 객체가 될 수 있다. Computer와 Phone이 갖고있는 기능들이 모두 포함되어야한다. 이 부분이 기능 구현을 강제(약속 또는 보증)한다고 한다.

 

 

class IPhone extends SmartPhone {

    public IPhone(String model) {
        super(model);
    }
		
		public abstract void authenticate();

		public void iCloud() { }
}

SmartPhone만으로는 객체를 만들 수 없다. 제조사와 모델이 들어가야 한다. 예시로 IPhone을 예시로 한다. IPhone클래스는 SmartPhone이라는 추상 클래스를 상속받아서 구체적으로 객체를 만들어내는 것이다.

출처: https://k3068.tistory.com/34

has-a 관계 → interface

위의 예시에서 인터페이스는 has-a관계를 설명한다.

스마트폰은 컴퓨터의 A기능, B기능을 가진다.

→ 스마트폰 Has A/B 기능

스마트폰은 전화의 C기능, D기능을 가진다

→ 스마트폰 Has C/D 기능

 

 

is-a관계 → abstract class

추상 클래스를 통해 해당 객체가 무엇인지 정의한다고 할 수 있다.

아이폰은 추상적인 스마트폰이라는 것을 구현한 객체이다.

→ 아이폰 is a 스마트폰

 

 

인터페이스 레퍼런스를 통해 구현체를 사용

class Macbook implements Computer {

    @Override
    public void playGame(String gameName) {...}

    @Override
    public void searchGoogle(String keyword) {...}
}

설명을 위해, Computer 인터페이스를 구현하기 위해 Macbook이라는 클래스를 정의했다.

 

이를 도식화하면 다음과 같이 표현할 수 있다.

Macbook 클래스와 IPhone은 공통적으로 Computer라는 인터페이스를 구현한 객체들이다. 즉, Computer의 기능들을 공통적으로 가지고 있다.

이런 특성을 통해 Computer라는 공통점을 코드로 구현해볼 수 있다.

 

 

Macbook air = new Macbook();
IPhone se = new IPhone("iphone se");

List<Computer> coms = new ArrayList<>();
coms.add(air);
coms.add(se);

coms라는 배열은 Computer라는 공통점을 지닌 객체를 허용한다.

서로 다른 클래스이지만, 서로 상위 인터페이스를 공유하기때문에 같은 배열에 들어갈 수 있게 되는 것이다.

즉, 객체의 상제정보를 제외하고 공통점(기능)을 통한 분류(classification)가 가능하다.

 

 

인터페이스의 default 메소드 - 자바8

자바8 이전에서는 인터페이스에서 오직 추상메소드만 정의가 가능했다. 하지만, 자바8 이후부터는 인터페이스에서 default, static 메소드 선언이 가능하다.

public interface Device {
	abstract void powerOn();
}

public class IPad implements Device {
	...
	@Override
	public void powerOn() {
		System.out.println("pressed power button");
	}
}

public class Macbook implements Device {
	...
	@Override
	public void powerOn() {
		System.out.println("pressed power button");
	}	
}

public class Car implements Device {
	...
	@Override
	public void powerOn() {
		System.out.println("car key is inserted");
	}
}

위는 자바8 이전의 인터페이스였던 경우, Device를 구현하는 모든 클래스는 powerOn()이라는 추상클래스를 재정의해야만 한다. 위의 예시에서처럼, 같은 내용이지만 다른 클래스이기때문에 개발자는 각 클래스마다 같은 내용을 재정의해야만 했다.

 

 

interface Device {
    default void powerOn() {
        System.out.println("pressed power button");
    }
}

public class IPad implements Device {
	...
}

public class Macbook implements Device {
	...
}

public class Car implements Device {
	...
}

자바8이후에는 default method가 추가됨으로써, Device 인터페이스를 implements하는 모든 클래스는 기본적으로 powerOn()메소드를 지니며, 이 메소드는 pressed power button이라는 메세지가 출력되는 것이 기본이 되는 겁니다. 마찬가지로, 실제 대부분의 기기(Device)들은 버튼을 눌러 전원을 킵니다. 차(Car)인 경우에만 키를 삽입해야 전원이 켜지는 것이죠. 결과적으로 코드의 양이 상당히 줄어들게 됩니다.

 

 

인터페이스의 static 메소드 - 자바 8

interface Device {
	...
	static void breakdown() {
		System.out.println("malfunctioning...");
	}
}

default method와 다른점은 static method는 Override를 통한 재정의가 불가능하다. 인터페이스의 static method는 어떤 클래스를 통해 구현을 하든 절대 바뀌지 않을 메소드에 대해서 사용할 수 있습니다.

기기(Device)의 경우, 부서진다면 어떤 기기이든 고장을 일으키게 되겠죠. 그렇기에 static method로 정의하기에 적절합니다.

 

 

인터페이스의 private 메소드 - 자바 9

출처 https://dev-coco.tistory.com/13 https://www.geeksforgeeks.org/private-methods-java-9-interfaces/

자바9부터는 인터페이스의 private method, private static method가 추가되었다.

이전에는 내부 기능을 처리하는 method임에도, 외부에 공개되어야하는 public의 형태로 선언되어야 했다. 그래서, 외부에서 캡슐화가 불가능했다.

private 메소드를 통해서 캡슐화가 가능하게 되었고, 사용자들에게 의도된 메소드만 공개되도록 설계할 수 있게 된것이다.

 

 

public interface Calc {
  
    public abstract void mul(int a, int b);
  
		public default void add(int a, int b)
    {
			  // private method inside default method
        sub(a, b); 
  
			  // static method inside other non-static method
        div(a, b);
        System.out.print("Answer by Default method = ");
        System.out.println(a + b);
    }
  
    public static void mod(int a, int b)
    {
        div(a, b); // static method inside other static method
        System.out.print("Answer by Static method = ");
        System.out.println(a % b);
    }
  
    private void sub(int a, int b)
    {
        System.out.print("Answer by Private method = ");
        System.out.println(a - b);
    }
  
    private static void div(int a, int b)
    {
        System.out.print("Answer by Private static method = ");
        System.out.println(a / b);
    }
}
  
class CalcApp implements Calc {
  
    @Override
    public void mul(int a, int b)
    {
        System.out.print("Answer by Abstract method = ");
        System.out.println(a * b);
    }
  
    public static void main(String[] args)
    {
        TempI in = new Temp();
        in.mul(2, 3);
        in.add(6, 2);
        TempI.mod(5, 3);
    }
}

 

반응형

'Dev > Java' 카테고리의 다른 글

[Java] 예외처리  (0) 2022.03.06
[Java] 패키지  (0) 2022.02.18
[Java] 메소드 디스패치  (0) 2022.02.16
[Java] 상속, super()  (1) 2022.02.15
[Java] 객체의 생성, 인스턴스화, 생성자, this 키워드  (0) 2022.02.09