ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Study] 자바 8주차 과제
    JAVA 2021. 1. 24. 16:36
    반응형

    자바 8주차 과제입니다.

     


     

    인터페이스 정의하는 방법

     

    자식 클래스가 여러 부모 클래스를 상속받을 수 있다면, 다양한 동작을 수행할 수 있다는 장점을 가지게 될 것입니다.

    하지만 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러 가지 문제가 발생할 수 있어 자바에서는 클래스를 통한 다중 상속은 지원하지 않습니다.

     

    하지만 다중 상속의 이점을 버릴 수는 없기에 자바에서는 인터페이스라는 것을 통해 다중 상속을 지원하고 있습니다.

    인터페이스(interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미합니다.

     

    자바에서 추상 클래스는 추상 메소드뿐만 아니라 생성자, 필드, 일반 메소드도 포함할 수 있습니다.

    하지만 인터페이스는 오로지 추상 메소드와 상수만을 포함할 수 있습니다.

    (자바 8버전부터는 default 예약어를 이용한 일반 메소드, static 메소드 구현이 가능하게 되었습니다.)

     

     

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

    인터페이스를 선언할 때에는 접근 제어자와 함께 interface 키워드를 사용하면 됩니다.

    단, 클래스와는 달리 인터페이스의 모든 필드는 public static final이어야 하며, 추상 메소드는 public abstract이어야 합니다.

    이 부분은 모든 인터페이스에 공통으로 적용되는 부분이므로 이 제어자는 생략할 수 있습니다.

    이렇게 생략된 제어자는 컴파일 시 자바 컴파일러가 자동으로 추가해 줍니다.

     

     

     

    인터페이스 구현하는 방법

     

    //class 클래스이름 implements 인터페이스 이름 {...}
    
    public interface Animal {
        void cry();
    }
    
    public class Cat implements Animal{
        @Override
        public void cry() {
            System.out.println("냐옹");
        }
    }
    
    public class Dog implements Animal{
        @Override
        public void cry() {
            System.out.println("멍멍");
        }
    }

    인터페이스는 추상 클래스와 마찬가지로 자신이 직접 인스턴스를 생성할 수는 없습니다.

    따라서 인터페이스가 포함하고 있는 추상 메소드를 구현해 줄 클래스를 작성해야만 합니다.

    단 키워드 'extends'가 아닌 구현한다는 의미의 'implements'를 사용합니다.

     

    만약 모든 추상 메소드를 구현하지 않는다면, abstract 키워드를 사용하여 추상 클래스로 선언해야 합니다.

     

     

    class 클래스 이름 extends 상위클래스 이름 implements 인터페이스 이름 {...}

    또 자바에서는 위와 같이 상속과 구현을 동시에 할 수 있습니다.

     

     

     

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

     

    다형성을 공부하게 되면 자식 클래스의 인스턴스를 부모 타입의 참조변수로 참조하는 것이 가능하다는 것을 알 수 있습니다. 인터페이스도 이를 구현한 클래스의 부모라 할 수 있으므로 해당 인터페이스 타입의 참조변수로 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로 형변환도 가능합니다.

     

     

    public class AnimalMain {
        public static void main(String[] args) {
            Animal cat = new Cat();
            Animal dog = new Dog();
            
            cat.cry(); //냐옹
            dog.cry(); //멍멍
        }
    }
    

     

     

     

    인터페이스 상속

     

    자바에서 다중 상속은 불가능하지만, 인터페이스는 예외입니다.

    인터페이스는 다중 상속, 즉 여러 개의 인터페이스로부터 상속 받는 것이 가능합니다.

    단, 인터페이스는 인터페이스로부터만 상속 받을 수 있습니다.

     

     

    public interface Movable {
        void move(int x, int y);
    }
    
    public interface Attackable {
        void attack();
    }
    
    public class Marine implements Movable, Attackable{
    
        @Override
        public void attack() {
            System.out.println("공격");
        }
    
        @Override
        public void move(int x, int y) {
            System.out.println(x + "," + y + "로 이동");
        }
    }
    

     

     

     

     

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

     

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

    인터페이스가 변경되지 않으면 제일 좋지만, 언젠가는 변경이 발생하기 마련입니다. 이를 해결하기 위해서 자바 8에서 기본 메소드 (default method)라는 것이 추가되었습니다. 디폴트 메소드는 추상 메소드의 기본적인 구현을 제공하는 메소드로, 추상 메소드가 아니기 때문에 디폴트 메소드가 새롭게 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 됩니다.

    디폴트 메소드는 앞에 키워드 default를 붙이며, 추상 메소드와 달리 일반 메소드처럼 구현부가 있어야 합니다. 접근 제어자는 public이며, 생략이 가능합니다.

     

    public interface Animal {
        void cry();
        default void defaultMethod() {
            System.out.println("디폴트 메소드");
        }
    }

     

    디폴트 메소드 충돌 규칙

    새로 추가된 디폴트 메소드가 기존의 메소드와 이름이 중복되어 충돌하는 경우 해결하는 규칙은 다음과 같습니다.

     

    • 여러 인터페이스의 디폴트 메소드 간의 충돌

      인터페이스를 구현한 클래스에서 디폴트 메소드를 오버라이딩 해야합니다.
    • 디폴트 메소드와 조상 클래스의 메소드 간의 충돌

      조상 클래스의 메소드가 상속되고, 디폴트 메소드는 무시됩니다.

    단순하게 필요한 쪽의 메소드와 같은 내용으로 오버라이딩해서 해결하는 방법도 있습니다.

     

     

     

     

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

     

    인스턴스 생성과 상관없이 인터페이스 타입으로 호출하는 메소드입니다.

    static 키워드를 사용하고, 접근 제어자는 항상 public이며 생략할 수 있습니다.

    디폴트 메소드와 마찬가지로 구현부가 있어야하지만 상속한 클래스에서 오버라이딩은 불가능합니다.

     

    public interface Animal {
        static void staticMethod() {
            System.out.println("스태틱 메소드");
        }
    }
    
    public class AnimalMain {
        public static void main(String[] args) {
        	//인터페이스 이름.method 형식으로 호출해야합니다.
            Animal.staticMethod();
        }
    }
    
    

     

     

     

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

     

    자바 8에서는 default method와 static method,

    자바 9에서는 private method와 private static method가 추가되었습니다.

     

    자바 9 이전에는 default method, static method에서 단지 특정 기능을 처리하는 내부 메소드일 뿐인데도, 외부에 공개되는 public 메소드로 만들어야 했습니다.

    인터페이스를 구현하는 다른 인터페이스 혹은 클래스가 해당 메소드에 접근하거나 상속할 수 있는 것을 원치 않아도 그렇게 할 수 밖에 없었던 것입니다.

     

    따라서 자바 9에서는 위와 같은 사항을 해결하기 위해 private method와 private static method라는 새로운 기능을 제공해줍니다. 이를 통해 코드의 중복을 피하고 인터페이스에 대한 캡슐화를 유지할 수 있게 되었습니다.

     

    public interface Animal {
        void cry();
        default void defaultMethod() {
            privateMethod();
            System.out.println("디폴트 메소드");
        }
    
        static void staticMethod() {
            privateStaticMethod();
            System.out.println("스태틱 메소드");
        }
    
        private void privateMethod() {
            System.out.println("private 메소드");
        }
        
        private static void privateStaticMethod() {
            System.out.println("private 스태틱 메소드");
        }
    }
    

     

     

     

    References

     

    - www.tcpschool.com/java/java_polymorphism_interface

    - yadon079.github.io/2021/java%20study%20halle/week-08

    - dev-coco.tistory.com/13

    - blog.baesangwoo.dev/posts/java-livestudy-8week/

    - www.notion.so/4b0cf3f6ff7549adb2951e27519fc0e6

     

    728x90

    댓글

Designed by Tistory.