추상클래스(abstract class)

  • 추상클래스란?

추상클래스는 추상메소드를 선언할 수 있는 클래스를 의미합니다. 또한 추상클래스는 클래스와는 다르게 상속받는 클래스 없이 그 자체로 인스턴스를 생성할 수는 없습니다.
추상메소드는 설계만 되어있으며 수행되는 코드에 대해서는 작성이 안된 메소드입니다.

미완성으로 남겨두는 이유는 상속받는 클래스 마다 반드시 동작이 달라지는 경우에 상속받는 클래스 작성자가 반드시 작성하도록하기 위함입니다.

추상 클래스 예제

abstract class Bird {
    private int x, y, z;

    void fly(int x, int y, int z) {
        printLocation();
        System.out.println("이동합니다.");
        this.x = x;
        this.y = y;
        if (flyable(z)) {
            this.z = z;
        } else {
            System.out.println("그 높이로는 날 수 없습니다");
        }
        printLocation();
    }

    abstract boolean flyable(int z);

    public void printLocation() {
        System.out.println("현재 위치 (" + x + ", " + y + ", " + z + ")");
    }
}

class Pigeon extends Bird {
    @Override
    boolean flyable(int z) {
        return z < 10000;
    }
}

class Peacock extends Bird {
    @Override
    boolean flyable(int z) {
        return false;
    }
}

public class Main {
    public static void main(String[] args) {
        Bird pigeon = new Pigeon();
        Bird peacock = new Peacock();
        System.out.println("-- 비둘기 --");
        pigeon.fly(1, 1, 3);
        System.out.println("-- 공작새 --");
        peacock.fly(1, 1, 3);
        System.out.println("-- 비둘기 --");
        pigeon.fly(3, 3, 30000);
    }
}
  • fly(x, y, z) 함수는 Bird 를 상속받는 모든 클래스에서 동일한 동작을 합니다. 다만, 그 안에서 호출된 flyable(z) 의 동작만 그것을 구현하는 자식 클래스에서 구현한대로 동작하는 것입니다.
  • 공작새(peacok)는 새이지만 전혀 날 수가 없죠? 그래서 공작새의 flyable() 은 항상 false 를 리턴해서 언제나 x,y 좌표로만 움직입니다. 반면에, 비둘기(pigeon)는 일정 높이까지는 날아갈 수 있기 때문에 그 기준(여기서는 10000)이 되기 전까지는 z좌표로도 움직일 수 있습니다. 이것을 새의 종류마다 중복코드 없이 구현하려면 추상클래스와 추상메소드를 이용해서 이렇게 구현할 수 있습니다. 이렇게 코드를 짜면, 중복코드가 없으면서도 새의 종류마다 주어진 위치까지 날 수 있는지를 판단할 수 있는 유연성을 허용하며 구현할 수 있습니다.

인터페이스(Interface)

  • 인터페이스란?

객체의 특정 행동의 특징을 정의하는 간단한 문법입니다.

인터페이스는 함수의 특징(method signature)인 접근제어자, 리턴타입, 메소드 이름만을 정의합니다

 interface 인터페이스명{
      public abstract void 추상메서드명();
    }

인터페이스 예제

interface Bird {
    void fly(int x, int y, int z);
}

class Pigeon implements Bird{
    private int x,y,z;

    @Override
    public void fly(int x, int y, int z) {
        printLocation();
        System.out.println("날아갑니다.");
        this.x = x;
        this.y = y;
        this.z = z;
        printLocation();
    }
    public void printLocation() {
        System.out.println("현재 위치 (" + x + ", " + y + ", " + z + ")");
    }
}

public class Main {

    public static void main(String[] args) {
        Bird bird = new Pigeon();
        bird.fly(1, 2, 3);
//        bird.printLocation(); // compile error
    }
}
  • interface인 Bird 타입으로 선언한 bird 변수는 실제로 Pigeon 객체이지만, interface인 Bird 에 선언되지 않은 printLocation() 이라는 함수는 호출할 수 없습니다. interface type 으로 선언되어있는 부분에서는 실제 객체가 무엇이든지, interface에 정의된 행동만 할 수 있습니다.

인터페이스 vs 추상클래스

  • 인터페이스
  1. 구현하려는 객체의 동작의 명세
  2. 다중 상속 가능
  3. implements를 이용하여 구현
  4. 메소드 시그니처(이름, 파라미터, 리턴 타입)에 대한 선언만 가능
  • 추상클래스
  1. 클래스를 상속받아 이용 및 확장을 위함
  2. 다중 상속 불가능 , 단일 상속
  3. extends를 이용하여 구현
  4. 추상메소드에 대한 구현 가능
복사했습니다!