본문 바로가기
개발/Java

추상클래스와 인터페이스

by BellOne4222 2024. 1. 29.

추상클래스와 인터페이스


다형성 보장

  • 부모가 명령을 내리면 자식이 반드시 동작(반응)을 해야한다.

  • 정보 은닉, Override(재정의), Upcasting, 동적 바인딩의 다형성 전제조건 4가지를 필수로 만족해야한다.

  • 반드시 재정의가 되어야 한다.

    • 부모 클래스가 추상적으로 설정하면 무조건 자식 클래스에서 재정의를 해야한다.
    • 재정의를 하면 다형성을 보장한다.
  • 부모 클래스를 추상적으로 만든다.

  • 추상 클래스(불완전한 클래스)

    • 메서드의 구현부가 없는 메서드
    • 반드시 자식이 완전하게 재정의를 통해 해야한다.
// 추상클래스(불완전한 클래스)
public abstract class Animal{

    // 추상 메서드(불완전한 메서드) : 메서드의 구현부가 없다.
    public abstract void eat();
}

public class IsNotOverride {
    public static void main(String[] args) {

        // 재정의를 안했기 때문에 -> 부모가 명령을 내리면(메세지를 보내면) 오동작을 한다.
        // [다형성을 보장하지 않음] -> 그러면 다형성을 보장할려면?(재정의를 강제로 하도록 만들어 주면 된다)
        // 추상클래스, 인터페이스 등장
        // [다형성이 보장이 된다.]

        Animal ani = new Dog();
        ani.eat();

        ani = new Cat();
        ani.eat();
    }
}

public class Cat extends Animal { // Animal->eat();
    // 재정의를 하지 않음(x) --->오류입니다(재정의를 하세요)
    // 부모가 추상적이기 때문에 재정의를 반드시 해야한다.-> 구현해야한다. 바디({   })를 만들면된다.
    public void night(){
        System.out.println("밤에 눈에서 빛이난다");
    }
    @Override
    public void eat() {
        System.out.println("고양이처럼먹다.");
    }
}

추상클래스와 다형성

  • 추상클래스란?
    • 다형성을 일부 보장하기 위해서 등장
    • 서로 비슷한 클래스의 공통 부분을 묶을 때 사용
    • 단독으로 객체를 생성 할 수 없다.
    • 부모의 역할로 사용한다.(Upcasting)
    • 구현된 메서드를 가질 수 있다.
    • 상속을 하다 보면 자연스럽게 추상클래스를 사용하게 된다.
    • public abstract void eat();

// 추상클래스(불완전한 클래스)
public abstract class Animal{

    // 추상 메서드(불완전한 메서드) : 메서드의 구현부가 없다.
    public abstract void eat();

    // 구현메서드
    public void move(){
        System.out.println("무리를 지어서 이동한다.");
    }
}

public class AbstractClassTest {
    public static void main(String[] args) {
        // 추상클래스는 단독으로 객체를 생성할 수 없다.
        // Animal ani = new Animal(); // cannot be instantiated(단독으로 객체를 생성 할 수 없다)
        Animal ani = new Dog(); // 추상 클래스는 부모의 역할은 할 수 있다.
        ani.eat(); // 개처럼 먹다
        ani.move();

        ani=new Cat();
        ani.eat(); // 고양이처럼먹다.
        ani.move();
        ((Cat)ani).night();
    }
}

인터페이스

  • 서로 다른 동작을 가지는 클래스를 상속관계로 만들어서 동작을 시켜야 한다고 가정해보자

    • 서로 다른 동작의 클래스도 공통기능을 만들어서 상속구조로 사용이 가능할까?
  • 일반 클래스

    • 재정의를 해도 되고 안 해도 되기 때문에 다형성을 보장 할 수 없다.
  • 추상 클래스

    • 재정의를 하게 만들어서 다형성을 보장 할 수 있지만 구현 클래스를 가질 수 있어서 하위 클래스가 오동작 할 수 있다.
      • 서로 다른 동작을 가지는 클래스 이기 때문에
  • 인터페이스를 이용한 클래스 동작

    • 다형성이 보장된다.
  • 인터페이스

    • 다형성을 100% 보장하기 위해서 등장
    • 서로 다른 클래스의 공통부분을 묶을 때 사용
    • 단독으로 객체를 생성 할 수 없다
    • 부모의 역할로 사용한다.(Upcasting)
    • 추상 메서드와 final static 상수만 올 수 있다.
    • 구현된 메서드를 가질 수 없다.
    • 다중 상속을 지원하기 위해 나타난 개념
  • 인터페이스에서 사용하는 final static 상수

    • 인터페이스 = 추상메서드 + final static 상수
    • final은 최종 → 변경 불가
  • 다중상속을 지원하는 인터페이스

    • 자바는 단일 상속

      
      // 자바는 단일 상속만 지원하지만 다중 상속처럼 보이게 할 수 있다.
      // Dog는 Animal 클래스를 상속 받고, Pet과 Robots 인터페이스를 구현했다.
      public class Dog extends Animal implements Pet, Robots{
      }
      
      // 인터페이스가 인터페이스를 상속
      public interface B extends A{
      }
      public class C implements B{
      }
      
      B obj = new C();
      A obj = new C();
  • 추상클래스 vs 인터페이스
    • 추상 클래스 : 추상메서드 + 구현 메서드
    • 인터페이스 : 추상메서드 + final static 상수
    • 공통점
      • 다형성을 보장 하기 위해서 등장 된 개념
      • 추상 메서드를 가질 수 있다
      • 단독으로 객체를 생성 할 수 없다
      • 부모의 역할로 사용한다.(Upcasting)
    • 차이점
      • 서로 비슷한 클래스의 공통 부분을 묶을 때 사용 → 추상 클래스
        • 추상 메서드와 구현 메서드를 가질 수 있다.
      • 서로 다른 클래스의 공통 부분을 묶을 때 사용 → 인터 페이스
        • 추상 메서드와 final static 상수를 가질 수 있다.
## 자바 최상위 클래스 Object

### Object 클래스를 이용하여 객체 생성하기

- 어떤 클래스 한 개를 만들 때 생략된 코드?
    - default pakage ( import java.lang)
    - java.lang.Object(최상위 클래스) : extends Object
    - default 생성자 : public A(){ super() }

- Object 클래스에 업캐스팅을 하면 자식 클래스의 메서드를 사용할 수 없기 때문에 다운 캐스팅을 하여서 사용

```java
Object obj = new A(); // Upcasting
        ((A)obj).display(); // Downcasting
```

### Object 클래스 다형성 인수로 활용

- Object 타입으로 Upcasting되면 반드시 Downcasting을 하게 되어 있다.

```java
public class ObjectPolyArg {
    public static void main(String[] args) {
        A a = new A();
        display(a);
        B b = new B(); // Upcasting
        display(b);
    }

    // Upcasting을 하면 Downcasting을 해야한다.
    private static void display(Object obj) { // 다형성 인수 활용
        if (obj instanceof A){
            ((A)obj).printGo(); // Downcasting
        }
        else{
            ((B)obj).printGo();
        }

    }

}
```

- 다형성 배열로 Object[] 배열 활용하기

    ```java
    public class ObjectPolyArray {
        public static void main(String[] args) {
            // A, B 클래스를 저장할 배열을 생성하세요
            Object[] obj = new Object[2]; // 다형성 배열
            obj[0] = new A();
            // ((A)obj[0]).printGo();

            obj[1] = new B();
            // ((B)obj[1]).printGo();

            display(obj);

        }

        private static void display(Object[] obj) {
            for (int i = 0; i < obj.length; i++) {
                if (obj[i] instanceof A){
                    ((A)obj[i]).printGo();
                }else{
                    ((B)obj[i]).printGo();
                }

            }
        }
    }
    ```


- Object 클래스의 toStirng()메서드
    - toString()
        - 객체의 번지를 문자열로 출력
        - Object안의 toString은 보통 재정의 해서 사용
        - `super.toString()); // 상위 클래스의 메서드 호출`

    ```java
    public class ObjectTostring {
        public static void main(String[] args) {
            Board b = new Board();
            b.setTitle("게시글입니다");
            // System.out.println(b.getTitle());

            System.out.println(b.toString()); // Object를 상속 받았기 때문에 b의 번지가 나온다.
            // fc.java.poly.Board@776ec8df(재정의 하기 전)
            // 게시글입니다 -> 재정의 한 후(toString())
        }
    }

    public class Board extends Object{
        private String title;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        // // Override
        // public String toString(){
        //     return title;
        // }

        @Override
        public String toString() {
            System.out.println(super.toString()); // 상위 클래스의 메서드 호출

            return "Board{" +
                "title='" + title + '\'' +
                '}';
        }
    }
    ```

'개발 > Java' 카테고리의 다른 글

자바 API  (0) 2024.01.29
자바 최상위 클래스 Object  (0) 2024.01.29
다형성  (0) 2024.01.29
객체 형변환  (0) 2024.01.28
상속  (1) 2024.01.28