[JAVA] 인터페이스

코박·2022년 3월 25일
0

JAVA

목록 보기
3/4
post-thumbnail

1.인터페이스 정의하는 방법

public interface 인터페이스명 {
//상수

타입 상수명 = 값;

//추상 메소드

타입 메소드명(매개변수, ... );

//디폴트 메소드

default 타입 메소드명(매개변수, ... ){

  //구현부

}

//정적 메소드

static 타입 메소드명(매개변수) {

  //구현부

}

}

상수 : 인터페이스에서 값을 정해줄테니 함부로 바꾸지 말고 제공해주는 값만 참조 (절대적)

추상메소드 : 가이드만 줄테니 추상메소드를 오버라이팅해서 재구현 (강제적)

default메소드 : 인터페이스에서 기본적으로 제공해주지만, 맘에 안들면 각자 구현(선택적)

정적메소드 : 인터페이스에서 제공해주는 것으로 무조건 사용 (절대적)

2.인터페이스 구현하는 방법

인터페이스에 정의된 추상 메서드를 완성하는 것

(implements를 사용한다는 것만 다르지, 추상 클래스 완성과 동일)

interface Fightable {
    void move(int x, int y);
    void attack(Unit u);
}
// Fighter 클래스는 Fightable 인터페이스를 구현
class Fighter implements Fightable {
    public void move(int x, int y) { /* 내용 생략 */ }
    public void attack(Unit u) { /* 내용 생략 */ }
}

일부만 구현하는 경우, 클래스 앞에 abstract를 붙여야 함

abstract class Fighter implements Fightable {
    public void move(int x, int y) { /* 내용 생략 */ }
    //public abstract void attack(Unit u) // 보이지 않지만 상속의 결과로 생략되어 있는 것
}

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

새로운 인터페이스를 정의했다면 새로운 reference data type을 정의, data type으로 interface name 이용

interface type을 가진 reference variable을 정의한다면 이 객체는 인터페이를 구현하는 클래스의 인스턴스여야 함

public Object findLargest(Object object1, Object object2) {
   Relatable obj1 = (Relatable)object1;
   Relatable obj2 = (Relatable)object2;
   if ((obj1).isLargerThan(obj2) > 0)
      return object1;
   else 
      return object2;
}

object1과 object2는 인터페이스 타입인 Relatable type으로 캐스팅될 수 있고 그래서 isLargerThan method를 사용 가능

4.인터페이스 상속

인터페이스의 조상은 인터페이스만 가능 (Object가 최고 조상 아님)

다중 상속이 가능 (∵ 추상 메서드는 충돌해도 문제 없음)

(상속에서 메서드 충돌문제 - 선언부가 똑같은데 구현부가 다른 것이 문제였음. 어느쪽을 상속받을지 결정할 수 없음)

// 구현부가 비었지만 상속 했으므로 멤버가 2개
interface Fightable extends Movable, Attackable { }

interface Movable{ void move(int x, int y); }
interface Attackable { void attack(Unit u); }

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

Default Method

인터페이스에 메소드 선언이 아니라 구현체를 제공하는 방법

public interface PrintName {
    void printName();

    default void printNameUpperCase(){
        System.out.println(getName().toUpperCase());
    }
    String getName();
}

해당 인터페이스를 구현한 클래스를 깨뜨리지않고 새 기능의 추가가 가능

기본 메소드는 구현체가 모르게 추가된 기능으로 리스크 발생 가능

ㄴ컴파일 에러는 아니지만 구현체에 따라 런타임 에러가 발생 가능

ㄴ반드시 문서화가 필요하다 (@implSpec 태그 사용)

/**
 * @ImplSpec
 * 이 구현체는 getName()으로 가져온 문자열을 대문자로 변환 후 출력
 */
default void printNameUpperCase(){
    System.out.println(getName().toUpperCase());
}

Object 가 제공하는 기능(equals, hasCode)는 기본메소드를 제공 불가

인터페이스를 상속받는 인터페이스에서 다시 추상 메소드로 변경 가능

인터페이스 구현체에서 재정의가 가능

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

Static Method

해당 타입 관련 헬퍼 또는 유틸리티 메소드를 제공할 때 인터페이스에 스태틱 메소드를 제공가능

public interface Foo {
    static void helloAll(){
        System.out.println("인삿말");
    }
}
public class App {
    public static void main(String[] args) {
        //static 메소드 사용
        Foo.helloAll();
    }
}

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

Private Method

인터페이스 내에서만 사용가능한 메서드

디폴트 메서드나 정적메서드에 사용하기 위해 작성되는 메서드

인터페이스를 구현하는 클래스쪽에서 재정의하거나 사용 불가

ㄴ 디폴트나 정적메서드를 통해서만 사용 가능

public interface Calc {
	
	double PI = 3.14; //나중에 상수가됨
	int ERROR = -9999999;
	
	int add(int num1, int num2);
	int substract(int num1, int num2);
	int times(int num1, int num2);
	int divide(int num1, int num2);
	//디폴트 메서드
	default void description() {
		System.out.println("정수 계산기를 구현합니다.");
		myMethod(); //private 메서드 사용
	}
	//static메서드
	static int total(int[] arr) {
		int total = 0;
		
		for(int i :arr) {
			total+= i;
		}
		mystaticMethod();//private static 메서드 사용
		return total;
	}
//private 메서드
	private void myMethod() {
			System.out.println("private method");
}
	//private static 메서드
	private static void mystaticMethod() {
		System.out.println("private static method");
	}

}

private static 메서드는 인터페이스 내에서만 사용가능하고 static 키워드가 있기에 static 메서드안에서만 사용가능하기 때문에 total에 사용

profile
웹 개발자 할래요

0개의 댓글