[Java] 인터페이스

케이·2022년 9월 9일
0

JAVA

목록 보기
12/17
post-thumbnail

학습한 내용을 정리한 포스팅입니다. 참고 문헌 내용이 직역 되어 어색한 문장이 있을 수 있습니다. 틀린 내용이 있다면 지적해주시면 감사하겠습니다.🙇🏻‍♀️

인터페이스 정의하는 방법

인터페이스는 추상메서드와 상수만 멤버로 가질 수 있다.

모든 메서드는 public abstract여야 하고 모든 멤버 변수는 public static final 이어야 한다. 그리고 이 둘은 생략이 가능하다. (static 메서드와 디폴트 메서드는 예외)

public interface GroupedInterpace extends Interface1, Interface2, Interface3 {
			// constant declarations

			// base of natural logarithms
			double E = 2.718282;

			//method signatures
			void doSomething(int i, double x);
			int doSomethingElse(String s);
}

인터페이스 구현하는 방법

인터페이스는 그 자체로는 인스턴스를 생성 할 수 없다 그렇기에 인터페이스를 구현할 클래스가 필요하다. 아래와 같이 인터페이스를 구현 할 수 있다.

class 클래스명 implements 인터페이스명 {
		//인터페이스에 정의된 추상 메서드를 구현해야 된다.
}

만일 구현하는 인터페이스의 메서드 중 일부만 구현하면 해당 클래스는 abstract를 붙여서 추상 클래스로 만들어줘야 한다.

또한 메서드를 오버라이딩 할 때 조상의 메서드보다 넓은 범위의 접근제어자를 지정해야하는 것이 인터페이스 구현에도 적용된다. 아래의 경우에서 move메서드가 public인 걸 볼 수 있는데 위에서 언급한 것 처럼 인터페이스 내의 메서드는 public abstract가 생략된 것이기 때문에 구현시에 접근 제어자를 public으로 해줘야 한다.

interface Movable {
	void move(int x, int y);
}

class Monster implements Movable {
	public void move(int x, int y) {
		//메서드 내용
	}
}

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

(사족: 지금도 내가 제대로 이해를 한건지 잘 모르겠다. 혹시 예제나 제가 써놓은 부분이 틀렸다면 꼭 지적.. 부탁드리겠습니다 ㅠㅅㅠ)

interface Attackable {
		void attack();
}

class Pikachu implements Attackable {
		
		@Override
		public void attack(){
				System.out.println("피카츄 백만볼트!!");
		}

		public void sleep(){
				System.out.println("zzz...");
		}
}

class Squirtle implements Attackable {
			
		@Override
		public void attack(){
				System.out.println("몸통박치기!!");
		}
}

public Attackable getMonster(String name){
		if(name.equals("피카츄")) {
				return new Pikachu();
		} else if (name.equals("꼬부기)) {
				return new Squirtle();
		} else {
				System.out.println("죄송합니다. 해당 몬스터는 아직 준비되지 않았습니다.");
		}
}

위의 예제에서 getMonster의 리턴타입이 Attackable이기 때문에 Attackable인터페이스를 구현한 클래스들(Pikachu, Squirtle)의 인스턴스를 반환한다.

인터페이스 타입으로 선언한 객체는 구현 클래스 내에서 생성한 메서드와 필드를 사용할 수 없다. 위의 경우에서는 Pikachu의 sleep 메서드를 사용할 수 없다. 사용하고 싶다면 캐스팅을 해야한다.


인터페이스 상속

인터페이스는 인터페이스로부터만 상속이 가능하고 여러개의 인터페이스로부터 상속을 받는 것이 가능하다.

interface Moveable {
	void move(int x, int y);
}

interface Attackable {
	void attack();
}

interface Fightable extends Moveable, Attackable {}
//Fightable에는 정의된 멤버가 없더라도 Moveable, Attackable에 정의 된 move와
//attack 메서드를 멤버로 갖게 된다.

인터페이스의 다중상속

인터페이스는 다중상속이 가능하다. 하지만 실제로 인터페이스로 다중 상속을 구현하는 경우는 거의 없다고 한다. 그 이유인 것이 다중 상속의 단점이 장점보다 더 크다고(상속을 여러개 받을 때 메서드의 선언부가 같거나 멤버 변수의 선언부가 같거나 하는 경우 어떤 조상으로 상속 받는 것인지 판단하기가 어렵다 등) 판단해서 자바에는 다중 상속을 포함하지 않았기 때문이다.(C++과 다르게)


인터페이스의 기본 메소드 (Default Method), 자바 8

디폴트 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로 추상 메서드가 아니기 때문에 디폴트 메서드가 새로 추가 되어도 인터페이스를 구현한 클래스를 변경하지 않아도 된다.

interface example {
	default void newMethod() {}
}

단, 새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌하는 경우가 발생한다. 이 충돌을 해결하는 규칙 두 가지가 있다.

  1. 여러 인터페이스의 디폴트 메서드 간의 충돌시 → 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩 해야 한다.
  2. 디폴트 메서드와 조상 클래스의 메서드 간의 충돌 → 조상 클래스의 메서드가 상속되고 디폴트 메서드는 무시된다.

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

원래는 추상메서드만 인터페이스에 선언할 수 있었는데 JDK 1.8부터 static 메서드도 추가할 수 있게 되었다.

구현체의 인스턴스를 생성하지 않고 인터페이스만으로 바로 메서드를 호출 할 수 있다.

interface Example1 {
		static void sayHello(){
				System.out.println("안녕하세요");
		}
}

public class ExampleClass {
		public static void main(String[] args){
				Example1.sayHello();
		}
}
// 안녕하세요 출력됨.

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

자바9부터는 인터페이스의 메소드에 private 메소드가 추가되었다. private 메서드가 추가됨으로써 얻는 가장 큰 장점은 캡슐화(encapsulation)이다. 또한 코드의 중복도 막을 수 있다.

interfaces are able to use private methods to hide details on implementation from classes that implement the interface. As a result, one of the main benefits of having these in interfaces is encapsulation.
Another benefit is (as with private methods in general) that there is less duplication and more re-usable code added to interfaces for methods with similar functionality.

(출처: https://www.baeldung.com/java-interface-private-methods)

예시)

인터페이스의 private 메서드 사용법

  • private 인터페이스 메서드는 추상메서드일 수 없고 abstract 접근 제어자와 같이 쓰일 수 없다.
  • private 메서드는 인터페이스 내부, static/non-static 인터페이스 메서드의 내부에서만 사용할 수 있다.
  • private non-static 메서드는 private static 메서드 안에서 사용될 수 없다.

참고

남궁성, 자바의 정석
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
https://www.baeldung.com/java-interface-private-methods
https://www.geeksforgeeks.org/private-methods-java-9-interfaces/

profile
삽질하며 깨닫고 배웁니다. (a.k.a 프로삽질러) + 이 구역의 회고왕

0개의 댓글