본문 바로가기
프로그래밍/Java

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

by 코딩중독 2023. 11. 14.

목차

    자바

    공통점

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

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

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

    * 부모의 역할로 사용한다. (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에 대한 내용을 담을 예정이다.