[자바/Java] 인터페이스(Interface)란?

resilient

·

2021. 1. 8. 22:15

728x90
반응형

github.com/whiteship/live-study/issues/8

 

8주자 과제: 인터페이스 · Issue #8 · whiteship/live-study

목표 자바의 인터페이스에 대해 학습하세요. 학습할 것 (필수) 인터페이스 정의하는 방법 인터페이스 구현하는 방법 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법 인터페이스 상속 인터

github.com

목표

자바의 인터페이스에 대해 학습하세요.

학습할 것 (필수)

  • 인터페이스 정의하는 방법
  • 인터페이스 구현하는 방법
  • 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
  • 인터페이스 상속
  • 인터페이스의 기본 메소드 (Default Method), 자바 8
  • 인터페이스의 static 메소드, 자바 8
  • 인터페이스의 private 메소드, 자바 9

마감일시

2021년 1월 9일 토요일 오후 1시까지.


#인터페이스란?

 

자바에서 .class 파일을 만들 때 보면 인터페이스라는 것이 있다.

인터페이스란 일종의 추상클래스 이다.

인터페이스는 추상메소드를 갖지만 추상화 정도가 높아서 추상 클래스와 달리 몸통을 갖춘 일반 메소드나 멤버 변수를 가질 수 없고, 추상메소드와 상수만을 가질 수 있다. 

인터페이스 또한 추상 클래스처럼 완성되지 않은 불완전한 것이기 때문에 다른 클래스를 작성하는데 도움을 주는 목적으로 사용된다.

 

#인터페이스 정의하는 방법

 

인터페이스를 정의하는 법은 클래스를 정의하는 법과 같다. 다만 키워드가 class가 아닌 interface라는 점만 다르다.

인터페이스도 접근제어자로 public이나 private를 사용할 수 있다. 

interface 인터페이스이름{
	public static final 타입 상수이름 = 값;
	public abstract 메소드이름(매개변수목록);
}

모든 멤버 변수는 public static final 이어야 하고 보통은 이 부분은 생략할 수 있다.

모든 메소드는 public abstract 이어야 하며, 이 부분 또한 생략해서 사용한다.

 

abstract 키워드는 클래스가 추상이면 인스턴스화 할 수 없기 때문에 사용된다.

 

#인터페이스 구현하는 방법

 

인터페이스는 그 자체로는 인스턴스를 생성할 수 없고, 자신에 정의된 추상메소드의 몸통을 만들어주는 클래스를 작성해야 하는데, 구현한다는 의미의 키워드 implements를 사용한다.

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

class Fighter implements Fightable{
	public void move(int x, int y){내용}
	public void attack(Unit z){내용}
}

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

 

new 키워드를 통해 인스턴스화 해준다.

class Fighter implements Fightable {
	public void move(int x, int y){내용}
	public void attack(Unit z){내용}
}
class test {
	public void main() {
		Fightable TEST = new Fighter();
		TEST.move();
		TEST.attack();
	}
}

이렇게 인터페이스를 상속받은 클래스가 인터페이스 타입을 가지고 클래스 Fighter을 가진 인스턴스를 생성한다.

 

 

#인터페이스 상속

 

인터페이스는 인터페이스로부터만 상속받을 수 있으며, 클래스와는 다르게 다중상속, 여러개의 인터페이스로 부터 상속을 받는 것이 가능하다.

interface Movable{
	void move(int x, int y);
}
interface Attack{
	void attack(Unit z);
}
interface Fight extends Movable, Attack{내용}

클래스 상속처럼, 자식 인터페이스는 부모 인터페이스에 정의된 멤버를 모두 상속받는다.

따라서 Fight 인터페이스는 move와 attack 메소드를 멤버로 갖게 된다.

 

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

 

JDK1.8부터 Default 메소드를 추가할 수 있다.

부모 클래스에 새로운 메소드를 추가하는 것은 별 일이 아니지만 인터페이스의 경우에는 별 일이다.

인터페이스에 메소드를 추가한다는 것은 추상 메소드를 추가한다는 거고 이 인터페이스를 구현한 기존의 모든 클래스들이 새로 추가된 메소드를 구현해야 하기 때문이다.

JDK 설계자들은 Defalult Method(기본 메소드)를 만들었다.

기본 메소드는 추상 메소드의 기본적인 구현을 구현하는 메소드이고 새로 추가되거나 하더라도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.

앞에 default 키워드를 붙이고, 추상 메소드와 달리 일반 메소드처럼 { } 이 있어야 한다. 접근제어자는 public이고 생략 가능하다. 

Default 메소드는 인터페이스를 구현한 클래스에서 오버 라이딩해주지 않으면 여러 인터페이스의  Default  메소드간에 충돌이 일어난다.

 

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

 

JDK1.8부터 static 메소드도 추가할 수 있게 되었다.

static 메소드는 인스턴스와 관계가 없는 독립적인 메소드이기 때문에 예전부터 인터페이스에 추가 못할 이유가 없었다.

하지만 규칙을 단순히 할 필요가 있어서 static메소드는 별도의 클래스에 따로 두어야 했다.

대표적인 것으로 java.util.Collection 인터페이스가 있다. java.util.Collection 와 관련된 static 메소드들이 인터페이스는 추상메소드만 선언할 수 있다는 규칙 때문에 별도의 Collection이라는 클래스에 들어갔던 것이다.

앞에 static 키워드를 붙이고, 접근제어자는 public으로 생략 가능하다.

 

#Default 메소드와 static 메소드 사용

public class Main {

	public static void main(String[] args) {
		Child c = new Child();
		c.method1();
		c.method2();
		MyInterface.staticMethod();
		MyInterface2.staticMethod();
	}
}
public class Child extends parent implements MyInterface,MyInterface2 {
	public void method1() {
		System.out.println("method1 in Child");
	}
}
public interface MyInterface {
	default void method1() {
		System.out.println("Method1 in MyInterface");
	}
	default void method2() {
		System.out.println("Method2 in MyInterface");
	}
	static void staticMethod() {
		System.out.println("staticMethod in MyInterface");
	}
}
public interface MyInterface2 {
	default void method2() {
		System.out.println("Method2 in MyInterface2");
	}
	static void staticMethod() {
		System.out.println("staticMethod in MyInterface2");
	}
}
public class parent {
	public void method2() {
		System.out.println("method2 in parent");
	}
}

 

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

 

Private 메소드는 해당 인터페이스의 내부에서만 접근 가능하도록 해서 인터페이스 내에서의 코드 재사용성과 효율성을 높였다.

상속되지 않고 외부에서 접근할 수 없다.

 

#Reference

반응형