티스토리 뷰

인터페이스(Interface)

  • 인터페이스는 일종의 추상 클래스이다.
  • 인터페이스는 추상 클래스처럼 추상 메서드를 갖지만 추상 클래스보다 추상화 정도가 높아서 추상클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다. 
  • 오직 추상 메서드와 상수만을 멤버로 가질 수 있다. 
  • 추상 클래스를 부분적으로만 완성된 '미완성 설계도' 라고 한다면, 인터페이스는 구현된 것은 아무것도 없고 밑그림만 그려져 있는 '기본 설계도' 이다.

인터페이스 정의

interface 인터페이스 이름 {
	public static final 타입 상수 이름 = 값;
    public abstract 메서드 이름(매개변수 목록);
}
  • inteface 키워드 사용 
  • interface에도 클래스와 같이 접근 제어자로 public 또는 default를 사용할 수 있다. 
  • 모든 멤버 변수는 public static final 이어야 하며, 이를 생략할 수 있다. 
  • 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다. 
  • 단, static, default 는 예외 
  • why?  인터페이스에 정의된 모든 멤버에 예외 없이 적용되는 사항이기 때문에 제어자를 생략할 수 있는 것이며, 편의상 생략하는 경우가 많다. 생략된 제어자는 컴파일 시에 컴파일러가 자동으로 추가해 준다. 

인터페이스 구현: implements

  • 인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없으며, 추상 클래스가 상속을 통해 추상 메서드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상 메서드의 몸통을 만들어주는 클래스를 작성해야 한다. 
  • 인터페이스를 구현하기 위해서는 'implements' 키워드를 사용한다. 
  • 인터페이스에 선언된 추상 메서드는 반드시 오버라이딩 해서 사용해야 하며, 인터페이스에 선언되어 있는 변수는 상수이므로 값을 변경할 수 없음에 유의해야 한다. 
class 클래스 이름 implements 인터페이스 이름 {
	...// 인터페이스에 정의된 추상 메서드 구현해야 한다. 
}
class Fighter implements Fightable {  // 구현 시 implements 키워드 사용
	public void move(int x, int y) { .... }
    public void attack(Unit u) { ...... }
}

 

인터페이스 구현: 익명클래스

  • 익명 클래스는 Inner class로, 이름이 없는 클래스를 말한다. 
  • 클래스 정의와 동시에 객체 생성이 가능하다. 
  • 익명 클래스를 사용하는 이유는 프로그램 내에서 한번 만 객체로 만드는데 사용되는 클래스를 굳이 정의할 필요가 없기 때문이다. 
// 익명클래스의 구조는 다음과 같다. 

인터페이스 인스턴스 = new 인터페이스(){
   // 인터페이스 구현
}
interface Monster {
	String getName();
}

public class Practice {
	public static void main(String[] args) {
		Monster monster = new Monster() {
	    	String name = "monster";
            @Override
	        public String getName(){
	        	return name;
	        }
	    };
	    System.out.println(monster.getName()); // monster
	}
}

 

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

interface Job {
	public void introduction(String name);
}

class Doctor implements Job{
	@Override
	public void introduction(String name) {
		System.out.println("YOUR JOB IS "+ name);
	}
}


public class Practice {
	public static void main(String[] args) {
		Doctor doctor01 = new Doctor();
		doctor01.introduction("a skin doctor");
		
		Job doctor02 = doctor01;
		doctor02.introduction("physician");
		
	}
}


// Result: 
//YOUR JOB IS a skin doctor
//YOUR JOB IS physician

 

인터페이스인 Job의 인스턴스 doctor02를 선언하면서 참조변수로 인터페이스 구현체인 Doctor의 인스턴스를 참조했다. 

인터페이스 상속

  • 자바에서는 인터페이스간 상속을 허용한다. 
  • 인터페이스간 상속시 'extends' 키워드를 사용한다. 
interface Athlete {
	void preSeason();
	void whileSeason();
}

interface BaseballPlayer extends Athlete { // 인터페이스간 상속시 'extends' 키워드 사용
	void postSeason();
}

class ProfessionalPlayer implements BaseballPlayer{ 
	@Override
	public void postSeason() {
		System.out.println("post season");
	}
	
	@Override
	public void preSeason() {
		System.out.println("pre season");
	}
	
	@Override 
	public void whileSeason() {
		System.out.println("시즌중");
	}
}

public class Practice {
	public static void main(String[] args) {
		ProfessionalPlayer proBaseballPlayer = new ProfessionalPlayer();
		proBaseballPlayer.preSeason();
		proBaseballPlayer.whileSeason();
		proBaseballPlayer.postSeason();
		
	}
}

//Result:
//pre season
//시즌중
//post season

 

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

  • 인터페이스는 원래 추상 메서드만 선언할 수 있었다. 그러나 Java8 부터 인터페이스에 default 메서드static 메서드를 추가하는 것이 가능해 졌다. 
  • Java8 이전의 인터페이스의 단점은 인터페이스에 변경사항이 발생하면, 해당 인터페이스를 구현하고 있는 모든 구현체를 수정했어야 한다는 것이었다. 예로, 인터페이스에 추상 메서드를 추가해야 할일이 발생한다면, 인터페이스 뿐만아니라 인터페이스를 구현하고 있는 모든 구현체에서 메서드를 추가하고 구현해야 했다. 
  • 이러한 단점의 해결책으로 나온 것이 default 메서드이다. default 메서드는 추상메서드가 아니기 때문에 메서드에 변경사항이 발생하더라도 구현체를 변경할 필요가 없다. 
interface 인터페이스 이름 {
	void 메서드1(); // 추상 메서드
    default void 메서드2(){
         // default 메서드 
    }
}

이렇게 메서드2를 default 메서드로 인터페이스에 추가하면, 모든 구현체에 메서드2를 구현할 필요없이 인터페이스만 수정하고, 사용하는 클래스에서 메서드를 사용하면 된다. 

 

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

  • Java8에 default 메서드와 함께 추가된 static 메서드는 default 메서드에 static 키워드를 선언하면 static 메서드가 된다. 
  • 구현체의 인스턴스를 생성하지 않고도 인터페이스 만으로 바로 메서드를 호출할 수 있다.
interface MyInterface {
	void method01();
	static void method02() {
		System.out.println("static method");
	}
}

public class Practice02 {
	public static void main(String[] args) {
		MyInterface.method02();
	}
}
//Result:
// static method

 

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

  • Java 9에서는 인터페이스에 private 메서드가 추가되었다. 
  • private 메서드가 추가되면서 인터페이스의 메서드를 외부에 공개하지 않을 수 있게 되었다. 
  • default 메서드처럼 구현체를 가져야 한다. 
  • 인터페이스 내부에서만 사용되는 메서드이다. 
  • private 메서드는 인터페이스의 static 키워드가 없는 메서드에서만, private static 메서드는 인터페이스의 모든 메서드에서 사용가능하다.
interface MyInterface {
   void method01();
   default void method02(){
      System.out.println("method 02 : default method");
      method04();
      method05();
   }
   static void method03(){
      System.out.println("method 03 : static method");
      // method04();  compile error
      method05();
   }
   private void method04(){
      System.out.println("method 03 : private method");
   }
   private static void method05(){
      System.out.println("method 04 : private static method");
   }
}

//참조: https://youngjinmo.github.io/2021/02/livestudy-week-08/#purpose

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함