CS 지식

추상 클래스와 인터페이스

이제하네 2024. 8. 25. 23:58

추상 클래스(Abstract Class)란 무엇인가?

추상 클래스(Abstract Class)는 객체지향 프로그래밍(OOP)에서 공통된 특성을 가지는 클래스들의 기본 구조를 정의하는 데 사용되는 중요한 개념입니다. 추상 클래스는 클래스 설계 시 다형성과 재사용성을 높여주며, 이를 활용하여 공통된 동작을 여러 하위 클래스에서 일관되게 구현할 수 있습니다. 

1. 추상 클래스란?

추상 클래스는 하나 이상의 추상 메서드를 포함할 수 있는 클래스입니다. 추상 메서드는 메서드의 시그니처(이름, 반환 타입, 매개변수 목록)만 정의하고, 실제 구현은 하위 클래스에서 제공됩니다. 추상 클래스는 그 자체로는 인스턴스화할 수 없으며, 반드시 이를 상속받은 구체적인 하위 클래스에서 인스턴스화가 가능합니다.

2. 추상 클래스의 특징

  1. 추상 메서드(Abstract Method):
    • 추상 클래스 내에 선언되는 메서드로, 메서드의 선언부만 있고 구현부는 없습니다.
    • 하위 클래스는 반드시 이 추상 메서드를 구현해야 합니다.
  2. 일반 메서드(Concrete Method):
    • 추상 클래스 내에는 구현된 일반 메서드도 포함될 수 있습니다.
    • 하위 클래스는 이 일반 메서드를 그대로 상속받아 사용할 수 있으며, 필요에 따라 오버라이딩할 수도 있습니다.
  3. 멤버 변수:
    • 추상 클래스는 일반 클래스처럼 멤버 변수를 가질 수 있습니다. 이 멤버 변수는 상태를 유지하며, 하위 클래스에서 상속받아 사용할 수 있습니다.
  4. 인스턴스화 불가능:
    • 추상 클래스는 인스턴스화할 수 없습니다. 즉, new 키워드를 사용하여 객체를 생성할 수 없습니다.
    • 인스턴스화를 위해서는 추상 클래스를 상속받은 하위 클래스에서 구체적인 구현을 제공해야 합니다.
  5. 단일 상속:
    • 자바에서는 한 클래스가 단 하나의 부모 클래스를 상속받을 수 있으며, 추상 클래스도 마찬가지로 단일 상속만 가능합니다. 따라서 한 클래스는 오직 하나의 추상 클래스를 상속받을 수 있습니다.

3. 추상 클래스를 사용하는 이유

  1. 공통된 동작의 재사용:
    • 여러 클래스에서 공통적으로 사용되는 동작이나 속성을 추상 클래스에서 정의하고, 이를 하위 클래스에서 상속받아 사용함으로써 코드의 중복을 줄일 수 있습니다.
  2. 다형성 구현:
    • 추상 클래스는 다형성을 구현하는 데 유용합니다. 상위 클래스의 타입으로 다양한 하위 클래스 객체를 참조할 수 있으며, 각 하위 클래스는 상위 클래스에서 정의된 메서드를 자신만의 방식으로 구현할 수 있습니다.

 

2-1
abstract class Animal {
    abstract void sound();  // 추상 메서드
}

=====================================
2-2
abstract class Animal {
    void sleep() {
        System.out.println("자야지");
    }
}
=====================================
2-4
abstract class Animal {
    abstract void sound();
}

class Dog extends Animal {
    void sound() {
        System.out.println("Bark!");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();  // 가능
        Dog dog = new Dog();        // 가능
        // Animal animal = new Animal();  // 오류: 추상 클래스는 인스턴스화할 수 없음
    }
}

=====================================
3-1
abstract class Animal {
    void breathe() {
        System.out.println("헥헥");
    }
    abstract void sound();
}

class Dog extends Animal {
    void sound() {
        System.out.println("왈왈");
    }
}

class Cat extends Animal {
    void sound() {
        System.out.println("야옹");
    }
}

=====================================
3-2

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.sound();  // 출력: 왈왈
        cat.sound();  // 출력: 야옹
    }
}

 

 

인터페이스(Interface)란 무엇인가?

인터페이스(Interface)는 객체지향 프로그래밍(OOP)에서 중요한 개념으로, 클래스가 특정 기능을 반드시 구현하도록 강제하는 계약(Contract) 역할을 합니다. 인터페이스는 구현 방법을 정의하지 않고, 오직 수행해야 할 동작(메서드)을 명시함으로써, 클래스 간의 일관성을 유지하고 다형성을 촉진합니다. 

1. 인터페이스란?

인터페이스는 클래스가 구현해야 할 메서드의 집합을 정의하는 일종의 청사진입니다. 인터페이스 자체는 메서드의 시그니처(이름, 반환 타입, 매개변수 목록)만을 포함하며, 실제 구현은 이를 구현하는 클래스에서 제공됩니다. 자바에서 인터페이스는 interface 키워드를 사용하여 정의합니다.

2. 인터페이스의 특징

  1. 추상 메서드(구현부가 없는 메서드):
    • 인터페이스 내의 모든 메서드는 기본적으로 추상적이며, 구현부를 가지지 않습니다. 구현하는 클래스는 이 메서드들을 반드시 구현해야 합니다.
     
  2. 다중 상속 가능:
    • 자바에서 클래스는 단일 상속만 가능하지만, 인터페이스는 다중 상속이 가능합니다. 즉, 한 클래스가 여러 인터페이스를 구현할 수 있습니다. 이를 통해 다양한 기능을 클래스에 추가할 수 있습니다.
     
  3. 상수(final static 변수):
    • 인터페이스는 상태를 가질 수 없지만, 상수를 정의할 수 있습니다. 인터페이스 내에서 선언된 변수는 기본적으로 public static final로 간주됩니다.
     
  4. 구현 강제성:
    • 인터페이스를 구현하는 클래스는 인터페이스에서 정의된 모든 추상 메서드를 구현해야 합니다. 만약 하나라도 구현하지 않으면, 해당 클래스도 추상 클래스로 선언해야 합니다.
     
2-1
interface Animal {
    void sound();  // 추상 메서드
}

=====================================
2-2
interface Jumper {
    void jump();
}

interface Swimmer {
    void swim();
}

class Duck implements Jumper, Swimmer {
    public void jump() {
        System.out.println("뛰다");
    }
    
    public void swim() {
        System.out.println("수영하다");
    }
}
=====================================
2-3
interface Constants {
    int MAX_SPEED = 100;  // public static final int MAX_SPEED = 100;
}
=====================================
2-4
interface Animal {
    void sound();
    
    // 디폴트 메서드
    default void breathe() {
        System.out.println("헥헥");
    }
    
    // 정적 메서드
    static void info() {
        System.out.println("동물들의 인터페이스");
    }
}
=====================================
2-5
class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("왈왈");
    }
}

3. 인터페이스를 사용하는 이유

  1. 다형성 구현:
    • 인터페이스를 사용하면 다양한 클래스에서 동일한 인터페이스를 구현하도록 강제함으로써, 다형성을 쉽게 구현할 수 있습니다. 예를 들어, 여러 클래스가 동일한 인터페이스를 구현하고 있다면, 해당 인터페이스 타입으로 객체를 참조하여 동적으로 메서드를 호출할 수 있습니다.
     
  2. 계약 기반 설계:
    • 인터페이스는 클래스 간의 계약을 정의합니다. 이를 통해 클래스는 특정 인터페이스를 구현함으로써 해당 기능을 반드시 제공해야 합니다. 이는 큰 규모의 프로젝트에서 팀 간 협업 시 매우 유용하며, 각 팀이 자신이 담당하는 부분을 계약에 따라 구현할 수 있습니다.
  3. 유연한 설계:
    • 인터페이스를 사용하면 클래스 설계를 유연하게 할 수 있습니다. 클래스가 특정 인터페이스를 구현함으로써 여러 역할을 수행할 수 있으며, 코드의 재사용성이 높아집니다. 예를 들어, 한 클래스가 여러 인터페이스를 구현하여 다양한 기능을 조합할 수 있습니다.
  4. 디커플링(Decoupling):
    • 인터페이스를 사용하면 클래스 간의 결합도를 낮출 수 있습니다. 구현 클래스의 구체적인 내용을 알 필요 없이, 인터페이스만으로 다른 클래스와 상호작용할 수 있기 때문에, 코드의 유연성과 유지보수성이 크게 향상됩니다.
interface Animal {
    void sound();
}

class Dog implements Animal {
    public void sound() {
        System.out.println("왈왈");
    }
}

class Cat implements Animal {
    public void sound() {
        System.out.println("야옹");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        Animal cat = new Cat();
        
        dog.sound();  // 출력: 왈왈
        cat.sound();  // 출력: 야옹
    }
}

'CS 지식' 카테고리의 다른 글

동기 ,비동기 처리  (0) 2024.09.02
SOLID 원칙  (0) 2024.09.01
오버로딩과 오버라이딩  (0) 2024.08.15
MVC 패턴  (0) 2024.08.11
객체 지향  (0) 2024.08.01