프로그래밍/Java

[Java] 추상클래스(abstract)와 인터페이스(interface)

코딩중독 2023. 11. 14. 23:44

자바

공통점

* 다형성을 보장하기 위해 등장한 개념

* 추상메서드를 가질 수 있다.

* 단독으로 객체를 생성할 수 없다.

* 부모의 역할로 사용한다. (Upcasting)

추상클래스 (abstract)

특징 (차이점) : 추상메서드와 구현메서드를 가질 수 있다. 상속(extends)을 받아서 사용한다.

1. 추상클래스 생성하기

public abstract class Person {
    // 구현메서드 3종
    public void walk() {
        System.out.println("걷는다.");
    }
    public void run() {
        System.out.println("달린다.");
    }
    public void sleep() {
        System.out.println("잠을 잔다.");
    }

    // 상속받은 클래스에서 재정의가 필요한 추상메서드
    public abstract void work();
}

 

자식클래스에서 동일하게 사용이 가능한 구현메서드 3개와 필수로 재정의가 필요한 1개의 추상메서드 구현

 

2. 추상클래스를 상속받는 2개의 클래스 생성하기

public class Father extends Person {
    @Override
    public void work() {
        System.out.println("회사에 출근을 한다.");
    }
}

public class Mother extends Person {
    @Override
    public void work() {
        System.out.println("집안일을 한다.");
    }
}

 

추상클래스인 부모클래스의 추상메서드(work())를 각각 재정의한 Father클래스와 Mother클래스

 

3. 준비된 클래스를 사용(실행)하는 메인클래스

public class AbstractUsage {
    public static void main(String[] args) {
        Person father = new Father();
        father.walk();
        father.run();
        father.sleep();
        father.work();  // 회사에 출근을 한다.
        System.out.println("===========");
        Person mother = new Mother();
        mother.walk();
        mother.run();
        mother.sleep();
        mother.work();  // 집안일을 한다.
    }
}

인터페이스 (interface)

특징 (차이점) : 추상메서드와 상수를 가질 수 있다. (구현메서드 X) 구현부(implements)에 사용한다.

1. 인터페이스 생성하기

public interface Person {
    void walk();
    void run();
    void sleep();
    void work();
}

 

구현메서드는 사용할 수 없다. 구현(implements)클래스에서는 추상메서드를 모두 재정의 해야한다.

2. 인터페이스를 구현하는 2개의 클래스 생성하기

public class Father implements Person {
    @Override
    public void walk() {
        System.out.println("빠르게 걷는다.");
    }

    @Override
    public void run() {
        System.out.println("천천히 달린다.");
    }

    @Override
    public void sleep() {
        System.out.println("일찍 잠을 잔다.");
    }

    @Override
    public void work() {
        System.out.println("회사에 출근을 한다.");
    }
}

public class Mother implements Person {
    @Override
    public void walk() {
        System.out.println("천천히 걷는다.");
    }

    @Override
    public void run() {
        System.out.println("빠르게 달린다.");
    }

    @Override
    public void sleep() {
        System.out.println("늦게 잠을 잔다.");
    }

    @Override
    public void work() {
        System.out.println("집안일을 한다.");
    }
}

 

같은 인터페이스(interface)를 구현하면서 추상메서드를 각각 다르게 재정의가 가능하다.

3. 준비된 클래스를 사용(실행)하는 메인클래스

public class InterfaceUsage {
    public static void main(String[] args) {
        Person father = new Father();
        father.walk();  // 빠르게 걷는다.
        father.run();   // 천천히 달린다.
        father.sleep(); // 일찍 잠을 잔다.
        father.work();  // 회사에 출근을 한다.
        System.out.println("===========");
        Person mother = new Mother();
        mother.walk();  // 천천히 걷는다.
        mother.run();   // 빠르게 달린다.
        mother.sleep(); // 늦게 잠을 잔다.
        mother.work();  // 집안일을 한다.
    }
}

 

재정의된 추상메서드에 따라 다른 결과가 나온다.

 

마치며...

추상클래스와 인터페이스의 차이점을 정확히 이해할 수 있는 시간이었다.

차이점을 정확하게 이해하고 사용해서 코딩을 한다면 깔끔한 코드를 만들어 낼 수 있을 것 같은 기분이 든다.

하지만 막상 코딩을 하면 항상 중복되는 코드가 나오기 마련이다.

꾸준한 리팩토링 작업을 거쳐서 부끄럽지 않은 코딩을 해야겠다.

다음 포스팅에서는 다형성의 연장선인 Upcasting과 Downcasting에 대한 내용을 담을 예정이다.