# Object Oriented Programming

**객체 지향 프로그래밍의 추상화와 다형성의 차이를 설명하고, 이를 실제 코드로 구현해 보세요.**

추상화

* 객체의 복잡성을 감추고 중요한 속성이나 동작에만 초점을 맞추는 개념.
* 인터페이스나 추상 클래스를 사용하여 객체의 공통된 동작을 정의

다형성

* 같은 메서드나 인터페이스가 다양한 객체에서 다른 방식으로 동작할 수 있는 능력을 의미.
* 메서드 오버라이딩 또는 인터페이스 구현을 통해 구현

```java
// 추상화와 다형성을 활용한 예제
abstract class Animal {
    // 추상화: 공통 행동 정의
    abstract void makeSound();

    void move() {
        System.out.println("The animal moves.");
    }
}

class Dog extends Animal {
    // 다형성: 구체적인 동작 구현
    @Override
    void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

class Cat extends Animal {
    // 다형성: 구체적인 동작 구현
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}

public class Main {
    public static void main(String[] args) {
        // 추상화를 활용한 다형성 사용
        Animal dog = new Dog();
        Animal cat = new Cat();

        dog.makeSound(); // Woof! Woof!
        dog.move();      // The animal moves.
        
        cat.makeSound(); // Meow!
        cat.move();      // The animal moves.
    }
}
```

1. 추상화와 다형성을 활용한 설계의 장단점은 무엇인가요?

장점:

* 유지보수성 향상
  * 추상화를 통해 코드를 모듈화하여 변경이 필요한 부분만 수정할 수 있습니다.
  * 다형성을 활용하면 새로운 기능 추가 시 기존 코드를 최소한으로 수정할 수 있습니다.
* 재사용성 증가
  * 공통된 인터페이스를 통해 재사용 가능한 코드를 작성
* 가독성 향상

단점:

* 복잡성 증가
  * 추상 클래스나 인터페이스가 많아지면 코드를 이해하기 어려워질 수 있습니다.
* 성능 저하
  * 다형성은 런타임에 실제 객체를 결정하므로 약간의 성능 오버헤드가 발생.



2. 추상화 계층이 많아질 경우 발생할 수 있는 문제는 무엇인가요?

* 가독성 저하
  * 계층이 많아지면 개발자가 실제 동작을 파악하기 어려워집니다.
* 오버엔지니어링
  * 필요 이상의 추상화를 추가하면 코드가 불필요하게 복잡해지고 유지보수가 어려워질 수 있습니다.
* 디버깅 어려움
  * 실제 호출되는 메서드나 객체를 추적하기 어려워 디버깅 과정이 복잡해질 수 있습니다.



3. 다형성을 활용한 설계에서 성능 최적화 방안은 무엇인가요?

* 메서드 인라이닝: 자주 호출되는 메서드를 컴파일 시점에 인라인으로 처리하도록 JVM의 JIT 최적화를 활용합니다.
* 적절한 추상화 수준 유지
* 캐싱 사용: 다형성을 통해 반환되는 객체를 캐싱하여 객체 생성 비용을 줄일 수 있습니다.
* Final 키워드 사용: 클래스나 메서드에 final 키워드를 적용하여 컴파일러가 최적화를 수행할 수 있도록 돕습니다.



4. 추상화와 다형성을 활용한 설계가 적합하지 않은 경우는 언제인가요?

* 성능이 중요한 시스템: 약간의 성능 오버헤드 발생
* 단일 목적의 간단한 애플리케이션
* 고정된 요구사항: 요구사항이 더 이상 추가되거나 변화하지 않는 경우



5. 추상화와 다형성을 활용한 설계에서 테스트 전략은 어떻게 수립하나요?

* 단위 테스트 (Unit Test)
  * 인터페이스나 추상 클래스의 구현체 별로 독립적인 테스트 케이스 작성.
* 통합 테스트 (Integration Test)
  * 여러 추상화 계층이 상호작용하는 시나리오를 테스트
* Mocking 활용
  * Mockito와 같은 라이브러리를 사용하여 추상 클래스나 인터페이스의 동작을 모킹합니다.
* 경계값 분석
  * 다형성의 다양한 구현체에 대한 경계값 및 edge case를 테스트합니다.



