JAVA Basic) 인터페이스 요소
Programming/Java 기초

JAVA Basic) 인터페이스 요소

반응형

 

목차


     

    <인터페이스 상수>

    인터페이스는 추상 메서드로 이루어지므로 인스턴스를 생성할 수 없으며 멤버 변수도 사용할 수 없다.
    근데 인터페이스에 아래 코드와 같이 변수를 선언해도 오류는 발생하지 않는다.

    public interface Calc{
    	double PI = 3.14;
        int ERROR = -99999999;
        ...
    }

    이 이유는 인터페이스에 선언한 변수를 컴파일 하면 상수로 변환되기 때문이다.

    Calc 인터페이스에 선언한 변수 PI를 컴파일 하면 상수 3.14, int형 변수 ERROR역시 -9999999~로 변환되어 상수로 취급된다.

    public static final double PI = 3.14;
    public static final int ERROR = -999999999;
    ...

     

    <디폴트 메서드와 정적 메서드>

    자바 7까지는 인터페이스에서 추상 메서드와 상수, 이 두 가지 요소만 선언해서 사용할 수 있었고, 자바 8부터는 인터페이스 활용성을 높이기 위해 '디폴트 메서드와 정적 메서드 기능을 제공'한다.
    '디폴트 메서드'인터페이스에서 구현 코드까지 작성한 메서드, '정적 메서드'인스턴스 생성과 상관 없이 사용할 수 있는 메서드다.
    하지만 디폴트, 정적 메서드를 추가했다고 해서 인터페이스가 인스턴스를 생성할 수 있는 것은 아니다.

    디폴트 메서드

    디폴트(default), 기본으로 제공되는 메서드이다. 디폴트 메서드는 인터페이스에서 구현되지만, 이후 인터페이스를 구현한 클래스가 생성되면 그 클래스에서 사용할 기본 기능이다. 디폴트 메서드를 선언할 때는 'default예약어'를 사용. 

    -Calc 인터페이스에 디폴트 메서드 구현

    package interfaceex;
    
    public interface Calc {
    	...
    	default void description() {
    		System.out.println("정수 계산기를 구현");
    	}
    }
    • 디폴트 메서드는 일반 메서드랑 똑같이 구현하면 됨.
    • 메서드 자료형 앞에 default예약어만 써주면 됨.

    -test클래스에서 확인하기

    package interfaceex;
    
    public class CalculatorTest {
    	public static void main(String[] args) {
    		int num1 = 10;
    		int num2 = 5;
    		
    		CompleteCalc calc = new CompleteCalc();
    		// CompleteCalc클래스 생성
    		
    		System.out.println(calc.add(num1, num2));
    		System.out.println(calc.substract(num1, num2));
    		System.out.println(calc.times(num1, num2));
    		System.out.println(calc.divide(num1, num2));
    		calc.showInfo();
    		
    		calc.description();	//default메서드 호출
    	}
    }

    디폴트 메서드는 인터페이스에 이미 구현되어있어서 인터페이스를 구현한 추상 클래스나, 이를 상속받은 CompleteCalc클래스에서 코드를 구현할 필요가 없다.

     

     

    디폴트 메서드 재정의

    만약 인터페이스에 이미 구현되어있는 디폴트 메서드가 새로 생성한 클래스에서 원하는 기능과 맞지 않는다면, 하위 클래스에서 디폴트 메서드를 재정의 할 수 있다. Calc인터페이스를 구현하는 Calculator에서도 재정의할 수 있고, 이를 상속받은 CompleteCalc에서도 가능하다.

    ...
    	@Override
    	public void description() {
    		// TODO Auto-generated method stub
    		super.description();
    	}// 디폴트 메서드를 재정의
    }

    super.description()은 인터페이스에 선언한 메서드를 의미. 사용하지 않는다면 지우고 새 코드를 작성하면 됨.

    정적 메서드

    정적 메서드는 static 예약어를 사용하여 선언, 클래스(인스턴스) 생성과 무관하게 사용할 수 있다.
    정적 메서드를 사용할 때는 인터페이스 이름으로 직접 참조하여 사용한다.

    그럼 Calc인터페이스에 매개변수로 전달된 배열의 모든 요소 값을 더하는 정적 메서드 total()을 추가해보자.

    package interfaceex;
    
    public interface Calc {
    	...	
    	static int total(int[] arr) {
    		int total = 0;
    		
    		for (int i : arr) {
    			total += i;
    		}
    		return total;
    	}// 인터페이스에 정적 메서드 total() 구현
    }

    메서드 자료형 앞에 static 예약어를 씀.

    테스트 프로그램을 다음처럼 작성하자.

    package interfaceex;
    
    public class CalculatorTest {
    	public static void main(String[] args) {
    	...
    		int[] arr = {1, 2, 3, 4, 5};
    		System.out.println(Calc.total(arr));
    	}
    }

    Calc.total(arr)처럼 인터페이스 이름으로 직접 참조하여 정적 메서드를 호출한다. total()메서드가 수행되면 배열의 모든 요소 값을 더한 결과 값을 반환하므로 1부터 5까지 모두 더한 값 15가 출력.

     

     

    <private 메서드>

    자바 9부터 인터페이스에 private 메서드가 구현할 수 있다. 'private메서드'는 인터페이스를 구현한 클래스에서 사용하거나 재정의할 수 없다.
    따라서 기존에 구현된 코드를 변경하지 않고 인터페이스를 구현한 클래스에서 공통으로 사용하는 경우에 private메서드로 구현하면 코드 재사용성을 높일 수 있다.

    'private메서드'는 코드를 모두 구현해야 하므로 추상 메서드에 private 예약어를 사용할 수는 없지만, static예약어는 함께 사용할 수 있다. priavate static 메서드는 정적 메서드에서 호출하여 사용.

    그러면 Calc 인터페이스에 private 메서드와 private static메서드를 구현하고 호출해 사용해보자.

    package interfaceex;
    
    public interface Calc {
    	...
    	default void description() {
    		System.out.println("정수 계산기를 구현");
    		myMethod();	//디폴트 메서드에서 private 메서드 호출
    	}
    	
    	static int total(int[] arr) {
    		int total = 0;
    		
    		for (int i : arr) {
    			total += i;
    		}
    		myStaticMethod();	//정적 메서드에서 private static 메서드 호출
    		return total;
    	}
    	
    	private void myMethod() {
    		System.out.println("private메서드 호출");
    	} //private 메서드
    	private static void myStaticMethod() {
    		System.out.println("private static 메서드 호출");
    	} //private static 메서드
    }

     

     

     

     

     

    반응형