럿고의 개발 노트

[프로그래머스] 자바 입문 > Part8. 인터페이스와 다른 형식의 클래스 본문

Java Note/[프로그래머스] 자바 입문(동영상 강의)

[프로그래머스] 자바 입문 > Part8. 인터페이스와 다른 형식의 클래스

KimSeYun 2020. 1. 29. 22:22

[프로그래머스] 자바 입문

Part8. 인터페이스와 다른 형식의 클래스

1. 인터페이스 만들기

인터페이스 만들기

  • 서로 관계가 없는 물체들이 상호 작용을 하기 위해서 사용하는 장치나 시스템을 인터페이스라고 함
  • 인터페이스 정의 방법
    • 추상 메소드와 상수를 정의할 수 있음.
    • 인터페이스에서 변수를 선언하면 컴파일 시 상수로 변함
  • 인터페이스에서 정의된 메소드는 모두 추상 메소드로 컴파일 시 추상 메소드로 자동 변경

인터페이스 사용하기

  • 인터페이스는 사용할때 해당 인터페이스를 구현하는 클래스에서 implements 키워드 이용
  • 인터페이스가 가지고 있는 메소드를 하나라도 구현하지 않는다면 해당 클래스는 추상 클래스가 됨.
    (추상클래스는 인스턴스를 만들 수 없음)
  • 참조변수의 타입으로 인터페이스를 사용 가능.
    이 경우에는 인터페이스가 가지고 있는 메소드만 사용 가능
  • 클래스는 인터페이스를 여러 개 구현 할 수 있음
public interface Tv {
    // 인터페이스를 왜 쓰는지가 어려울 수 있음
    // 객체를 만들때 객체가 어떤 기능을 가지고 있을지 고민해야 함

    // 볼륨을 0 ~ 100까지 사용한다는 것
    // 상수를 만들수 있는데, final이 없어도 상수 생성이 가능한게 특징
    // 변수를 생성하면 컴파일시 자동으로 final을 붙여 상수 처리 함
    public int MIN_VOLUME = 0; 
    public int MAX_VOLUME = 100;

    // 추상클래스를 정의할때, 추상메서드를 만들때 비슷
    // 그러나 인터페이스는 인터페이스 자체가 구현은 없고 메소드(기능)만 가지고 있는 것 이기 때문에
    // 추상메서드 처럼 absolute가 필요 없는 것
    public void turnOn();
    public void turnOff();
    public void changeVolume(int volumne);
    public void changeCannel (int channel);
}
public class LedTv implements Tv { 
    // TV가 가지고 있는 모든 기능을 LedTV에서도 기능해야 함.

    @Override
    public void turnOn() {
        System.out.println("켜다");
    }

    @Override
    public void turnOff() {
        System.out.println("끔");
    }

    @Override
    public void changeVolume(int volumne) {
        System.out.println("볼륨조정");
    }

    @Override
    public void changeCannel(int channel) {
        System.out.println("채널조정");
    }
}
public class LedExam {
    public static void main(String[] args) {
        Tv tv = new LedTv(); // 참조타입으로 인터페이스를 사용 가능
        tv.turnOn();
        tv.changeCannel(8);
        tv.changeVolume(39);
        tv.turnOff();
        // 동일한 인터페이스를 구현다는 것은 클래스 사용법이 같다는 것을 의미
    }
}

2. 인터페이스와 default method

인터페이스의 default 메소드

  • Java8이 등장하면서 interface에 대한 정의가 몇 가지 변경
  • default 메소드
    • 인터페이스가 default 키워드로 선언되면 메소드 구현 가능.
    • 이를 구현하는 클래스는 default메소드를 overriding(오버라이딩) 가능
    • 인터페이스가 변경되면, 인터페이스를 구현하는 모든 클래스들이 해당 메소드를 구현해야 하는 문제가 있는데 해결하기 위해 인터페이스에 메소드를 구현해 놓을 수 있도록 함.
  • static 메소드
    • 인터페이스에 static 메소드를 선언함으로써, 인터페이스를 이용한 간단한 기능을 가지는 유틸리티성 인터페이스 생성 가능
public interface Calculator {
    // JAVA8이 등장하면서 interface에 대한 정의가 몇 가지 변경되었다.
    // 기존 인터페이스는 추상 메서드만 가지고 있었음
    // 그러나 JAVA8부터는 default method와 static method를 지원함
    // default method : 메서드를 구현할 수 있으며, 또한 이를 구현하는 클래스는 default메소드를 오버라이딩 할 수 있음

    public int plus(int i, int j);
    public int multiple(int i, int j);

    // default 키워드를 이용하여 메소드 구현 가능
    default int plus1(int i, int j) {
        return i + j;
    }

    // static 메서드 : 인터페이스를 이용한 간단한 기능을 가지는 유틸리티성 인터페이스 생성 가능
    public static int multiple2(int i, int j) {
        return i * j;
    }
}
public class MyCal implements Calculator {

    @Override
    public int plus(int i, int j) {
        return i + j;
    }

    @Override
    public int multiple(int i, int j) {
        return i * j;
    }
}
public class MyCalExam {
    public static void main(String[] args) {
        Calculator cal = new MyCal();

        System.out.println(cal.plus(1, 2));
        System.out.println(cal.multiple(1, 2));
        System.out.println(cal.plus1(1, 2)); // default메소드인데, MyCal에서는 Override로 구현하지 않았지만 실행 가능
        // default메소드이기 때문에 가능!

        // JAVA8에서 default메소드를 추가한 이유는
        // 인터페이스가 변경되면, 인터페이스를 구현하는 모든 클래스 들이 해당 메소드를 구현해야 하는 문제가 있는데
        // 이런 문제를 해결하기 위해서 인터페이스에 메소드를 구현해 놓을 수 있도록 함

        // static한 메소드는 인터페이스에서만 실행 가능
        // MyCal에서는 실행 불가
        Calculator.multiple2(1, 2);
    }
}

3. 내부클래스

내부클래스

  • 클래스 안에 선언된 클래스를 내부 클래스라고 한다.
  • 어느 위치에 선언하느냐에 따라서 4가지 형태가 존재
    • 클래스 안에 인스턴스 변수. 즉, 필드에 선언하는 위치에 선언되는 경우 보통 중첩클래스 혹은 인스턴스 클래스라고 함.
    • 내부 클래스가 static으로 정의된 경우, 정적 중첩 클래스 또는 static 클래스라고 함.
    • 메소드 안에 클래스를 선언한 경우, 지역 중첩 클래스 또는 지역클래스라고 함.
    • 익명클래스
public class InnerExam {
    // 내부 클래스 : 클래스 안에 선언된 클래스
    //1. 중첩클래스 또는 인스턴스 클래스 : 클래스 안에 인스턴스 변수, 즉 필드를 선언하는 위치에 선언되는 경우
    class Cal {    // 내부 클래스 - 중첩 클래스
        int value = 0;
        public void plus() {
            value++;
        }
    }

    public static void main(String[] args) {        
        // 내부클래스 - 중첩 클래스 사용 방법
        InnerExam ie = new InnerExam();
        InnerExam.Cal cal = ie.new Cal();
        cal.plus();
        System.out.println(cal.value);
    }
}
public class InnerExam2 {
    // 2. 정적 중첩 클래스 또는 static 클래스
    // 필드 선언할 때 스태틱한 필드로 선언한 것과 같음.
    static class Cal {
        int value = 0;
        public void plus() {
            value++;
        }
    }

    public static void main(String[] args) {
        // 내부클래스 - static 클래스
        InnerExam2.Cal cal = new InnerExam2.Cal();
        cal.plus();
        System.out.println(cal.value);
    }
}
public class InnerExam3 {
    // 지역 중첩 클래스 또는 지역 클래스
    // 메소드 안에 클래스 선언
    public void exec() {
        class Cal {
            int value = 0;
            public void plus() {
                value++;
            }
        }

        Cal cal = new Cal();
        cal.plus();
        System.out.println(cal.value);
    }

    public static void main(String[] args) {
        InnerExam3 t = new InnerExam3();
        t.exec();
    }
}

익명클래스

  • 익명 중첩 클래스라고도 함.
  • 생성자 다음에 중괄호 열고 닫고가 나오면, 해당 생성자 이름에 해당하는 클래스를 상속받는 이름없는 객체를 만든다는 것을 뜻함.
  • 괄호 안에는 메소드를 구현하거나 메소드를 추가할 수 있음.
  • 익명클래스를 만드는 이유는 상속받는 클래스를 만들 필요가 없을 경우. 즉, 상속받는 클래스가 해당 클래스에서만 사용되고 다른 클래스에서는 사용되지 않는 경우
public abstract class Action {
    // 일반 추상 클래스
    public abstract void exec();    
    // 익명 중첩 클래스 = 익명 클래스 < 내부클래스
}
public class ActionExam{
    public static void main(String[] args) {
        // 일반 추상 클래스
        // Action action = new MyAction();
        // action.exec();        
        // 익명 클래스 : 해당 생성자 이름에 해당하는 클래스를 상속받는 이름 없는 객체를 만드는 것
        // 만드는 이유는 Action을 상속받을 Class를 만들 필요가 없을때 사용
        // 예를 들면, 여기서만 Action을 한번만 사용하면 이게 더 간단할수 있음
        Action action = new Action() {
            @Override
            public void exec() {
                System.out.println("exec");
            }
        };
        action.exec();
    }
}
public class MyAction extends Action {
    @Override
    public void exec() {
        System.out.println("exec");
    }
}

※ 출처

[프로그래머스] 자바 입문

Comments