JAVA/java 이론

[자바JAVA]인터페이스 / 상속/ 구현/다형성/ default메서드/static메서드

자바칩 프라푸치노 2020. 10. 29. 18:16

이 포스팅에는 아래의 내용이 포함되어있습니다.

1. 인터페이스

2.인터페이스의 상속

3. 인터페이스의 구현

4. 인터페이스의 장점

5. 인터페이스를 통한 다형성

- 직접적 관계

- 간접적 관계

6. defalt메서드

- static메서드

 

 

1. 인터페이스란? Interface

- 일종의 추상클래스

- 추상클래스보다 추상도가 높다.

- 한마디로 객체 사용 설명서라고 한다.

- 실제 구현된 것이 하나도 없는 기본 설계도이다.

- 추상메서드와 상수, 디폴트 메서드 만을 멤버로 가질 수 있다. ( static 메서드는 가능)

- 인스턴스를 생성할 수 없다.

 

(예제)

1
2
3
4
5
6
7
public interface A {
 
    void method(); //추상메서드선언
//public abstract 생략 - 반드시 추상메서드임
 
}
 
cs

인터페이스는 이렇게 만들어줍니다

그리고 메서드는 method()이지만 public abstract가 저절로 생략되어있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
public class Member implements A{
 
    @Override
    public void method() {
        System.out.println("인터페이스A를 구현한 클래스 Member의 method()호출됨");
    }
 
    public void method1() {
        System.out.println("Member클래스 만 있는 method1()호출됨");
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
public class Person implements A{
 
    @Override
    public void method() {
        System.out.println("인터페이스A를 구현한 클래스 Person의 method()호출됨");
    }
 
    public void method1() {
        System.out.println("인터페이스를 구현한 클래스에서 새로 만든 메서드입니다.");
    }
}
 
cs

인터페이스를 구현한 클래스는 implements로 인터페이스를 구현해줍니다.

그리고 인터페이스의 추상메서드를 구현해줍니다.

method1은 각 클래스의 고유 메서드입니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Example {
 
    public static void main(String[] args) {
 
        A a = new Person();//A인터페이스를 구현했다라는 것은 구현클래스의 일종의 조상
        Person person = new Person();
        
        Person person2 = (Person)a;//다운캐스팅
        person2.method();
        person2.method1();
        System.out.println();
        
        a.method();
        person.method();
        person.method1();
        
        A a1 = new Member();//인터페이스 필드의 다형성
        a1.method();
        //a의 근본은 A라는 인터페이스이다. 하지만 A인터페이스에는 method1()이 존재하지 않는다
        //하여 다형성에서 배웠듯이 근본은 절대 벗어나지 못한다. 
        //a1.method1();
        
    }
 
}
 
cs

실행클래스입니다.

인터페이스도 다형성이 적용되어 일종의 조상인 인터페이스 A클래스로 자손의 객체를 생성할 수 있습니다.

 

<실행결과>

인터페이스를 구현한 객체에서 인터페이스에 있던 메서드를 부르면 각 클래스에서 오버라이딩한 값이 나옵니다.


2. 인터페이스의 상속

클래스와 달리 다중 상속 허용

통상적으로 인터페이스는 ~able(~할수있는)으로 선언된다.

Object클래스 같이 최고 조상이 없다.

생성자가 없다.

 

 

3. 인터페이스 구현

상속과 구현이 동시에 가능하다.

인터페이스에 정의된 추상메서드를 완성해야한다.

추상메서드를 일부만 구현하면 클래스 앞에 abstract 를 붙여야한다(추상클래스이다)

 

4. 인터페이스의 장점

- 개발 시간을 단축시킬 수 있다.

- 표준화가 가능하다

-서로 관계없는 클래스에게 관계를 맺어줄 수 있다.

- 독립적인 프로그래밍이 가능하다.

 

5. 인터페이스를 이용한 다형성

상속과 같습니다.

예제를 통해 살펴보겠습니다.

 

찬찬히 코드를 살펴보십쇼

1
2
3
4
5
6
7
8
9
10
11
package sec02_exam;
//직접적 관계에 놓인 클래스 A와 B
//A클래스는 B클래스를 사용하는 입장
public class A {
 
    //매개값이 클래스B타입이다. 다시말해, B가 변경이 있으면, A에도 영향을 미친다.
    public void methodA(B b) {
        b.methodB();
    }
}
 
cs
1
2
3
4
5
6
7
8
9
package sec02_exam;
 
public class B {
 
    public void methodB() {
        System.out.println("직접적 관계인 클래스 A를 통한 MethodB()");
    }
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package sec02_exam;
 
public class InterfaceEx {
 
    public static void main(String[] args) {
 
        //클래스 B가 다 완성되어야 비로소 클래스 A에 선언 되어있는 
        //methodA()를 호출할 수가 있다. (이것이 직접적 관계이다.)
        
        A a = new A();
        B b = new B();
        
        a.methodA(b);
        a.methodA(new B());
    }
 
}
 
cs

A클래스에 methodA에는 매개변수로 B를 넣고 있습니다.

직접적으로 B를 사용하는 것이지요

<출력결과>

 


코드를 이렇게 조금 바꿔보았습니다.

인터페이스 I를 선언하였습니다.

1
2
3
4
5
6
7
package sec03_exam;
 
public interface I {
//추상메서드
    void methodB();
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
package sec03_exam;
 
public class A {
//클래스 B가 완성 되지 않아도 선언부 즉 인터페이스에 있는 추상메서드인
//선언부만 알고 있으면 언제든지 호출이 가능해진다.
//이것이 간접적 관계인 것이다. 
    public void methodA(I i) {
        i.methodB();
    }
}
 
cs

매개변수에 인터페이스를 넣었습니다.

그럼 여기 매개변수에 올 수 있는 타입은 인터페이스 I를 구현한 모든 클래스들이 올 수 있습니다.

그 클래스의 methodB를 호출하는 것입니다.

 

1
2
3
4
5
6
7
8
9
package sec03_exam;
 
public class B implements I{
//인터페이스만 바라보고, 선언되어있는 메서드를 오버라이딩 하고있다.
    public void methodB() {
        System.out.println("인터페이스를 통한 MethodB()호출");
    }
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package sec03_exam;
 
public class InterfaceEx {
 
    public static void main(String[] args) {
        //클래스를 직접 생성해서 호출하는 것
        A a = new A();
        a.methodA(new B());//매개변수의 다형성
        //B클래스는 일종의 I인터페이스의 자손이라서
        //매개변수로 들어올 수 있다.
        
        //인터페이스의 필드의 다형성
        I i = new B(); //구현관계이기 때문에 생성가능
        i.methodB(); 
    
    }
 
}
 
cs

 

인터페이스를 통해서 간접적인 관계를 맺고 있습니다.

인터페이스 클래스의 추상메서드의 선언부만 알아도 호출을 할 수 있습니다.

 

<출력 결과>


6. default메서드

인터페이스에 변경이 있을 시,

인터페이스를 구현한 클래스들에서 다 인터페이스의 메서드를 구현해야하기 때문에

오류가 빠바바박 올라옵니다.

그래서 구현부가 있는 메서드를 선언할 수 있는 것입니다.

 

default를 꼭 붙여주어야하며 구현클래스에서 오버라이딩이 가능합니다.

 

코드를 찬찬히 살펴보십쇼

인터페이스를 선언했습니다.

default메서드가 있고 static 메서드가 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package sec06_exam;
 
public interface MyInterface {
 
    //JDK 1.8부터 아래 2개의 메서드가 인터페이스 멤버로 추가되었다.
    //1. default메서드는 기본적으로 public 접근 제한을 갖는다.
    //블럭(구현부가 존재하는 메서드)
    public default void method1() {
        System.out.println("인터페이스에 선언된 디폴트 메서드1 호출");
    }
    default void method2() {
        System.out.println("인터페이스에 선언된 디폴트 메서드2 호출");
        }
    //정적메서드
    static void staticMethod() {
        System.out.println("인터페이스에 선언된 정적 메서드 호출");
        
    }
}
 
cs

 

인터페이스를 구현한 클래스입니다.

인터페이스에 있던 메서드 어떠한 것도 필수적으로 오버라이딩 하지 않았습니다.이로써 default메서드와 정적메서드는 꼭 구현을 하지 않아도 된다는 것을 알 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package sec06_exam;
 
public class Myclass implements MyInterface{
 
    //MyInterface 인터페이스를 구현함
    //단, 인터페이스에 디폴트메서드와 static메서드만 있기에 재 정의할 메서드가 없다.
    //인터페이스에 추상메서드가 있으면 반드시 재정의가 필요
    public void method() {
        System.out.println("MyClass에서 호출한 메서드");
    }
    
    @Override
    public void method1() {
        System.out.println("MyInterface에 있는 디폴트 메서드 method1()을 오버라이딩한 메서드 호출");
    }
    
}
 
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package sec06_exam;
 
public class Default_StaticExample {
 
    public static void main(String[] args) {
 
        Myclass myclass = new Myclass();
        myclass.method();
        myclass.method1();
        myclass.method2();
        //MyInterface인터페이스에 있는 정적메서드 호출방법
        //인터페이스명.정적메서드 명
        MyInterface.staticMethod();
        
        MyInterface myInterface = new Myclass();
        myInterface.method1();
        myInterface.method2();
 
    }
 
}
 
cs

 

인터페이스를 구현한 클래스의 인스턴스를 만들어서 메서드들을 출력합니다.

그리고 static메서드는 인터페이스명.메서드명으로 출력이 가능합니다.

 

인터페이스로 필드의 다형성을 통해 구현한 클래스의 객체를 생성할 수 있습니다.

그러나 여기서는 근본이 인터페이스이기 때문에 인터페이스에 있는 메서드만 호출이 가능합니다.

method()는 구현 클래스에만 있는 메서드이기 때문에 호출할 수 없습니다.

<실행결과>

728x90