전 포스트에 이어서 다형성과 추상화에 대해서 알아보자
객체 지향 언어의 특징 중 다형성은 같은 타입이지만, 다양한 동작을 수행할 수 있도록 하는것인데,
이번에도 코드와 함께 보도록 하자.
public class Animal {
public void makeSound() {
System.out.println("동물이 소리를 냅니다.");
}
}
public class Dog extends Animal {
public void makeSound() {
System.out.println("개가 멍멍 짖습니다.");
}
}
public class Cat extends Animal {
public void makeSound() {
System.out.println("고양이가 야옹야옹 웁니다.");
}
}
Animal 클래스는 공통 특성을 나타내는 부모 클래스인데,
개와 고양이 클래스는 Animal 클래스를 상속받아 makesound 메서드를 재정의(앞에서말한 오버라이딩)하여 개와 고양이 특성을 나타내도록 한것이다.
그리고 이제 다형성을 활용해보자.
public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Animal();
Animal dog = new Dog();
Animal cat = new Cat();
animal.makeSound(); // 동물이 소리를 냅니다.
dog.makeSound(); // 개가 멍멍 짖습니다.
cat.makeSound(); // 고양이가 야옹야옹 웁니다.
}
}
Animal 클래스 타입의 변수 animal, Dog 클래스 타입의 변수 dog, Cat 클래스 타입의 변수 cat을 생성하고, 이들에 각각 Animal, Dog, Cat 클래스의 인스턴스를 할당하여 다형성을 활용해 본것이다.
이렇게 하면 변수 animal, dog, cat은 모두 Animal 클래스 타입으로 선언되었지만, 각각 다른 클래스의 인스턴스를 가리키므로 makeSound 메서드를 호출할 때 각각 다른 결과가 나오게 된다.
이런것이 객체지향언어의 다형성이다. 이를 통해서 코드의 재사용성, 유지보수성이 증가하게 된다.
객체들의 공통된 특성을 뽑아내는 과정이라도 정의할 수 있는데, 객체를 일반적인 개념으로 바라보고 객체들의 공통점을 찾아내어 추상적인 개면으로 정의하는것이다.
이렇게 추상화된 개념을 클래스로 정의하고 객체를 생성할 때 이 클래스를 사용한다.
나 같은 원시인은 코드를 봐야지 이해를 잘하기 때문에 예시를 들어보겠다.
도형(shape)클래스를 추상화 하고 싶다고 가정해보겠다.
이 클래스는 면적을 구하기 위한 메소드를 제공한다.
실제로는 구체적인 도형에 대한 정보를 제공하지 않는다.
클래스를 추상 클래스로 만들어, 추상 클래스는 추상 메소드를 포함할 수 있으며, 이 메소드는 하위 클래스에서 구현해야 한다. 추상 클래스에서 getArea()와 같은 추상 메소드를 정의할 수 있다.
abstract class Shape {
abstract double getArea();
}
자 이제 실제 도형을 나타내는 하위 클래스를 만들어 보자.
예를 들어 사각형, 삼각형 클래스를 만들고, 이 클래스들은 도형 클래스에서 정의한 'getArea()' 메소드를 구현해야한다.
class Rectangle extends Shape {
double width;
double height;
double getArea() {
return width * height;
}
}
class Triangle extends Shape {
double base;
double height;
double getArea() {
return 0.5 * base * height;
}
}
이렇게 하면 사,삼각형 클래스는 도형 클래스에서 정의한 'getArea()' 메소드를 구현하므로 면적을 계산할 수 있게된다.
위 코드와 같이 추상화는 OOP에서 개념을 단순화 하고 일반화하는 방법이다. 추상화 클래스와 인터페이스 사용하여 추상화를 구현할 수 있다.