[JAVA] 객체 지향 핵심 – 다운 캐스팅 과 추상 클래스 구현 및 응용

– 다운 캐스팅

자바에서 다운캐스팅(Downcasting)은 상위 클래스 타입의 참조 변수를 하위 클래스 타입으로 변환하는 것을 말합니다. 다운캐스팅은 객체 지향 프로그래밍에서 다형성을 활용할 때 주로 사용됩니다.

– 다운캐스팅의 기본 개념

  1. 업캐스팅(Upcasting): 하위 클래스 타입의 객체를 상위 클래스 타입으로 변환하는 것. 이는 자동으로 이루어집니다.
  2. 다운캐스팅(Downcasting): 상위 클래스 타입의 객체를 하위 클래스 타입으로 변환하는 것. 이는 명시적으로 변환을 요구하며, 런타임에 타입 검사를 수행합니다.
  3. instanceof 연산자: 다운캐스팅을 안전하게 수행하기 위해 사용되는 연산자. 객체가 특정 클래스의 인스턴스인지 확인합니다.
  • 업캐스팅된 클래스를 다시 원래의 타입으로 형 변환
  • 하위 클래스로의 형변환은 명시적으로 해야 함

– instanceof를 이용하여 인스턴스의 형 체크

  • 원래 인스턴스의 형이 맞는지 여부를 체크하는 키워드 맞으면 true 아니면 false를 반환 함
import java.util.ArrayList;

class Animal{
    public void move(){
        System.out.println("동물이 움직입니다.");
    }
}
class Human extends Animal{
    public void move(){
        System.out.println("사람이 두발로 걷습니다.");
    }
    public void readBook(){
        System.out.println("사람이 책을 읽습니다.");
    }
}
class Tiger extends Animal{
    public void move(){
        System.out.println("호랑이가 네 발로 뜁니다.");
    }
    public void hunting(){
        System.out.println("호랑이가 사냥을 합니다.");
    }
}
class Eagle extends Animal{
    public void move(){
        System.out.println("독수리가 하늘을 날아갑니다.");
    }
    public void flying(){
        System.out.println("독수리가 날개를 펴고 날아갑니다.");
    }
}

public class AnimalTest {
    public static void main(String[] args) {

        Animal hAnimal = new Human();
        Animal tAnimal = new Tiger();
        Animal eAnimal = new Eagle();

        ArrayList<Animal> animalsList = new ArrayList<Animal>();
        animalsList.add(hAnimal);
        animalsList.add(tAnimal);
        animalsList.add(eAnimal);

        for (Animal ani : animalsList) {
            ani.move();
        }
        animalMove(hAnimal);
        animalMove(tAnimal);
        animalMove(eAnimal);

        AnimalTest test = new AnimalTest();
        test.testDowncasting(animalsList);
    }

    public static void animalMove(Animal animal){
        animal.move();
    }
    public static void testDowncasting(ArrayList<Animal> animalsList){
        for (int i = 0; i < animalsList.size(); i++){
            Animal animal = animalsList.get(i);

            if (animal instanceof Human){
                Human human = (Human) animal;
                human.readBook();
            }
            else if (animal instanceof Tiger){
                Tiger tiger = (Tiger) animal;
                tiger.hunting();
            }
            if (animal instanceof Eagle){
                Eagle eagle = (Eagle) animal;
                eagle.flying();
            }
        }
    }
}

– 추상 클래스

자바에서 추상 클래스(Abstract Class)는 공통적인 특성과 행동을 정의하고, 구체적인 구현은 하위 클래스에서 제공하도록 하는 중요한 객체 지향 프로그래밍 개념입니다. 추상 클래스는 인스턴스화할 수 없으며, 하나 이상의 추상 메서드를 포함할 수 있습니다.
  • 구현 코드 없이 메서드의 선언만 있는 추상 메서드(abstract method)를 포함한 클래스
  • 메서드 선언(declaration) : 반환타입, 메서드 이름, 매개변수로 구성
  • 메서드 정의(definition) : 메서드 구현(implementation)과 동일한 의미 구현부 (body)를 가짐
  • 예) add(int x, int y); //선언
    int add(int x, int y){} //구현부가 있음, 추상 메서드 아님!
  • abstract 예약어를 사용
  • 추상 클래스는 new할 수 없음 (인스턴스화 할 수 없음)

– 구현

  • 메서드에 구현 코드가 없으면 abstract 로 선언
  • abstract 로 선언된 메서드를 가진 클래스는 abstract 로 선언
  • 모든 메서드가 구현 된 클래스라도 abstract로 선언되면 추상 클래스로 인스턴스화 할 수 없음
  • 추상 클래스의 추상 메서드는 하위 클래스가 상속 하여 구현
  • 추상 클래스 내의 추상 메서드 : 하위 클래스가 구현해야 하는 메서드
  • 추상 클래스 내의 구현 된 메서드 : 하위 클래스가 공통으로 사용하는 메서드 (필요에 따라 하위 클래스에서 재정의 함)
public abstract class Computer {
    public abstract void display();
    public abstract void typing();

    public void turnOn(){
        System.out.println("전원을 켭니다.");
    }
    public void turnOff(){
        System.out.println("전원을 끕니다.");
    }

}

public class DeskTop extends Computer {
    @Override
    public void display() {
        System.out.println("DeskTop display");
    }
    @Override
    public void typing() {
        System.out.println("DeskTop typing");
    }
    @Override
    public void turnOff(){
        System.out.println("DeskTop turnOff");
    }

}

public abstract class NoteBook extends Computer {

    @Override
    public void typing() {
        System.out.println("NoteBook typing");
    }
}

public class MyNoteBook extends NoteBook{
    @Override
    public void display() {
        System.out.println("MyNoteBook display");
    }
}

public class ComputerTest {
    public static void main(String[] args) {

        Computer deskTop = new DeskTop();
        deskTop.display();
        deskTop.turnOff();


        NoteBook myNoteBook = new MyNoteBook();
        myNoteBook.display();
        myNoteBook.typing();

    }
}

– 응용 (템플릿 메서드)

  • 추상 메서드나 구현 된 메서드를 활용하여 코드의 흐름(시나리오)를 정의하는 메서드
  • final로 선언하여 하위 클래스에서 재정의 할 수 없게 함
  • 프레임워크에서 많이 사용되는 설계 패턴
  • 추상 클래스로 선언된 상위 클래스에서 템플릿 메서드를 활용하여 전체적인 흐름을 정의 하고 하위 클래스에서 다르게 구현되어야 하는 부분은 추상 메서드로 선언하여 하위 클래스에서 구현 하도록 함
public abstract class Car {
    public abstract void drive();
    public abstract void stop();
    public abstract void fuel();
    public void startCar(){
        System.out.println("시동을 켭니다.");
    }
    public void turnOff(){
        System.out.println("시동을 끕니다.");
    }
    public void washCar(){ //훅 메서드 - 확장의 여지를 줌.
    }
    final public void run(){
        startCar();
        drive();
        stop();
        turnOff();
        fuel();
        washCar();
    }

}

public class AiCar extends Car {
    @Override
    public void drive() {
        System.out.println("차를 주행합니다.");
        System.out.println("차동차가 스스로 방향을 바꿉니다.");
    }
    @Override
    public void stop() {
        System.out.println("차동차가 스스로 멈춥니다.");
    }
    @Override
    public void fuel() {

    }
}

public class ManualCar extends Car{

    @Override
    public void drive() {
        System.out.println("사람이 운전합니다.");
        System.out.println("사람이 핸들을 조작합니다.");
    }
    @Override
    public void stop() {
        System.out.println("브레이크를 밟아서 정지합니다.");
    }
    @Override
    public void fuel() {

    }
    public void washCar(){
        System.out.println("손세차를 합니다.");
    }
}

public class CarTest {
    public static void main(String[] args) {
        Car aiCar = new AiCar();
        aiCar.run();

        System.out.println("==========================");

        Car menualCar = new ManualCar();
        menualCar.run();

    }
}

Leave a Comment