ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바의정석 Ex7_11 인터페이스
    Java/자바의정석 2023. 2. 21. 13:53
    반응형
    package Chap07;
    
    class Ex7_11 {
        public static void main(String[] args) {
            Child3 c = new Child3();
            c.method1();
            c.method2();
            MyInterface.staticMethod();
            MyInterface2.staticMethod();
        }
    }
    
    //인터페이스는 다중 상속이 가능 ,로 연결
    class Child3 extends Parent3 implements MyInterface, MyInterface2 {
        Child3(){
            System.out.println("Child3 객체 생성");
        }
        @Override
        public void method1() {
            System.out.println("method1() in Child3");
        }
    }
    
    class Parent3 {
        public void method2() {
            System.out.println("method2() in Parent3");
        }
    }
    
    interface MyInterface {
        //default -> 제어자
        default void method1(){
            System.out.println("method1() in MyInterface");
        }
    
        default void method2() {
            System.out.println("method2() in MyInterface");
        }
        default void method3() {
            System.out.println("method3() in MyInterface");
        }
    
        static void staticMethod() {
            System.out.println("staticMethod() in MyInterface");
        }
    }
    
    interface MyInterface2 {
        default void method1() {
            System.out.println("method1() in MyInterface2");
        }
        static void staticMethod() {
            System.out.println("staticMethod() in MyInterface2");
        }
    }
    

    ============실행결과=============

    Child3 객체 생성
    method1() in Child3
    method2() in Parent3
    staticMethod() in MyInterface
    staticMethod() in MyInterface2

     

     

    연습문제를 풀기전에 기본적인 개념부터 짚고 넘어가보자.


    인터페이스란?

    • 추상메서드의 집합
    • 구현된것이 전혀 없는 껍데기

    추상메서드는 다시 구현을 해야하고 구현된것이 하나도 없는 껍데기는 왜 사용해야할까?

     

    붕어빵을 만드는 예시를 들어보자. 

    붕어빵을 만들때에는 틀이 필요하다. 하지만 붕어빵 기계는 틀(껍데기)만 존재할뿐 붕어빵(구현된것)이 없다.

    붕어빵기계(인터페이스)를 만들어둔다면 이 기계만 들고가서 자신에게 맞는 붕어빵을 구현시킬수있다.

    슈크림 혹은 팥 등 자신의 기호에 맞게 말이다.

     

    이렇게 인터페이스의 장점은 여러명이서 같은 작업을 할때 인터페이스를 작성함으로써 더욱 편리하게 활용이 가능하다.

     

     

    인터페이스는 추상메서드의 집합이라고 하였는데 인터페이스 내부에는 몇가지 규칙이있다.

    • 접근제어자로 public , default, static(Java8부터 추가)
    • 모든 멤버변수는 public static final 이여야하며, 이를 생략할 수 있다. (인스턴스변수 iv, 클래스변수 cv 구현 불가능)
    • 모든 메서드는 public abstract 이여야하며, 이를 생략할 수 있다.
    • 오직 추상메서드와 상수만을 구성원으로 가질 수 있다.

    위와같은 조건들이있는데. 추상메서드만이 존재한다면 상속받은 클래스는

    매번 추상 메서드를 재정의해줘야하는 불편함이 있다. 그래서 구현부까지 구현이 가능한 메서드가 있다.

     

    메서드 앞에 Default 예약어를 붙여준다. 

    interface MyInterface {
        //default -> 제어자
        default void method1(){
            System.out.println("method1() in MyInterface");
        }
    
        default void method2() {
            System.out.println("method2() in MyInterface");
        }
        default void method3() {
            System.out.println("method3() in MyInterface");
        }
    
        static void staticMethod() {
            System.out.println("staticMethod() in MyInterface");
        }
    }

    이와같이 default 예약어를 붙인다면 필수로 {}구현부를 구현해주어야하며 자신의 필요에따라 해당 메서드를 오버라이딩하여 사용하면된다. 여기서 또 오버라이딩의 조건을 한번 다시 생각해보자.

     

    오버라이딩의 조건은?

    • 메서드 이름이 같아야한다.
    • 매개변수가 같아야한다.
    • 반환타입이 같아야한다.

    또한 이러한 인터페이스들은 다중 상속이 가능하다.

    class Child3 extends Parent3 implements MyInterface, MyInterface2 {
        Child3(){
            System.out.println("Child3 객체 생성");
        }
        @Override
        public void method1() {
            System.out.println("method1() in Child3");
        }
    }

    인터페이스의 경우 extends가 아닌 implements를 선언하여 상속을 한다.

    ,를 이용하여 다중 선언이 가능하다는 점 참고하자.

     

     

    자 이제 연습문제를 다시 보러들어가보면 main에서

    Child3 c = new Child3();

     

    와같이 Child3반환타입의 c 참조변수를 선언하여 객체를 생성하였다.

    class Child3 extends Parent3 implements MyInterface, MyInterface2 {
        Child3(){
            System.out.println("Child3 객체 생성");
        }
        @Override
        public void method1() {
            System.out.println("method1() in Child3");
        }
    }

     객체를 생성하였을때 기본생성자가 호출이되어 'Child3객체 생성' 메서드가 실행된다.

    c.method1();
    c.method2();

    다음으로 참조변수를 통해 해당 메서드를 호출한다.

    c.method1의 경우 Child3와 상속받은 Interface에 동시에 존재함으로 Child3쪽에서 원하는 방식으로 오버라이딩하였다.

     

    c.method2의 경우 인터페이스가 아닌 클래스를 상속받았다.

    class Parent3 {
        public void method2() {
            System.out.println("method2() in Parent3");
        }
    }
    

    Parent3 클래스의 경우에는 Interface를 상속받지 않았기 때문에 @Override를 붙여준다면 에러가 발생한다.

    오버라이딩된 메서드가 아닌 단지 Child3의 부모가 가지고있는 method2()가 호출된다.

     

    MyInterface.staticMethod();
    MyInterface2.staticMethod();

     

    interface MyInterface {
        //default -> 제어자
        default void method1(){
            System.out.println("method1() in MyInterface");
        }
    
        default void method2() {
            System.out.println("method2() in MyInterface");
        }
        default void method3() {
            System.out.println("method3() in MyInterface");
        }
    
        static void staticMethod() {
            System.out.println("staticMethod() in MyInterface");
        }
    }
    
    interface MyInterface2 {
        default void method1() {
            System.out.println("method1() in MyInterface2");
        }
        static void staticMethod() {
            System.out.println("staticMethod() in MyInterface2");
        }
    }

     

    마지막으로 참조변수 없이 곧장 인스턴스를 참조하여 메서드를 호출한다.  static이기 때문에

    인터페이스명을 참조하여 바로 호출이 가능하다.

    반응형

    댓글

Designed by Tistory.