[JAVA] 추상화 & 다형성

림민지·2025년 3월 4일

Today I Learn

목록 보기
15/62

1️⃣ 추상화

: 불필요한 정보를 제거하고 본질적 특징만 남기는 것.
유지보수성이 좋은 프로그램

공통적인 속성기능을 정의
→ 코드의 중복 ↓
→ 클래스 간 관계를 효과적으로 설정

1. abstract 제어자

abstract가 클래스나 메서드에 붙으면, 자동으로 추상 클래스와 추상 메서드가 된다. => 미완성된 클래스나 메서드라고 생각하면 된다.
abstract class 클래스 () { --- } 이렇게 추상 클래스로 작성되어있다면, 이건 상속을 통해 내부의 추상 메서드를 구현해주어야 한다.

2.Interface & implements

인터페이스는 추상 클래스의 일종이다.

  • 설계에 있어서 가이드를 제공 (최소한의 규격을 정의)
    → 개발자마다 서로 다른 방식으로 메서드를 만든다면 일관성이 깨질 수 있기 때문
  • 세부 구현은 각 클래스에서
  • 일관성은 유지, 클래스가 고유한 특색으로 확장함

인터페이스는 implements 키워드를 통해 활용할 수 있다.

🐈 예시

LifeForm 인터페이스를 상속한 Animal 인터페이스, 그리고 두 인터페이스를 활용하는 Cat, AnimalMain 클래스로 알아보자

//LifeForm 인터페이스
public interface LifeForm {
    void exists();
}

extends 키워드를 통해 LifeForm 인터페이스를 Animal 인터페이스가 상속받았다.

//Animal 인터페이스
public interface Animal extends LifeForm{
    void makeSound();
}

implements 키워드를 통해 Animal 인터페이스를 활용할 수 있다

//Cat 클래스
public class Cat implements Animal{
    @Override
    public void exists(){
        System.out.println("cat is exist");
    }

    @Override
    public void makeSound() {
        System.out.println("Meow");
    }

    public void scratch(){
        System.out.println("scratch");
    }
}
//AnimalMain 클래스
public class AnimalMain {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.exists();
        cat.makeSound();
        cat.scratch();
    }
}

AnimalMain 클래스를 실행하면 기능들이 상속되어 출력되는 모습을 확인할 수 있다. 이처럼 상속과 추상화를 잘 활용하면, 개발자들에게 틀을 제공하므로서 중복 없이 더 효과적으로 코딩할 수 있다.


2️⃣ 다형성 (Polymorphism)

: 하나의 타입으로 여러 객체를 다룰 수 있는 기술이다!
보통 하나의 객체는 하나의 타입으로 고정되어 있지만, 다형성을 사용하면 하나의 객체가 다른 타입으로 사용될 수 있다는 뜻이다.

위의 추상화 개념을 활용해 다형성을 구현해보자

  1. 부모 타입은 자식 타입을 담을 수 있다.
  2. 자식은 부모를 호출할 수 없다!!

1. 다형적 참조

자바에서 부모 타입은 자신은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다. => ✨다형적 참조✨

예제를 통해 이해해보자.

👨‍👩‍👧‍👦 예제

Parent클래스와 그를 상속하는Child클래스, 그리고 PolyMain 메인 클래스를 만들어보자

public class Parent {
    public void parentMethod(){
        System.out.println("Parent.parentMethod");
    }
}

extends로 Parent 클래스를 상속한다

public class Child extends Parent{
    public void childMethod(){
        System.out.println("childMethod");
    }
}
public class PolyMain {
    public static void main(String[] args) {
        System.out.println("부모가 부모 참조");
        Parent parent = new Parent();
        parent.parentMethod();

        System.out.println("자식이 자식 참조");
        Child child = new Child();
        child.childMethod();
        child.parentMethod();

        System.out.println("부모가 자식 참조");
        Parent poly = new Child();
        poly.parentMethod();

    }
}

PolyMain코드를 보자.
Parent클래스와 Child 클래스가 자신의 인스턴스를 참조하는 것은 당연히 가능하다.
여기서 다형성을 이용한다면,
부모 클래스인 Parent 클래스는 자식 클래스인 Child 클래스를 참조할 수 있다
하지만 반대는 불가능하다(컴파일 오류가 발생한다)

자바에서 부모 타입은 자신은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다. ➡️ 다형적 참조

이때 부모타입으로 자식 타입을 다룰 수 있었던 이유는 바로 자동 형변환(Casting) 덕분이다!

2. 형변환 Casting

자식 → 부모 : 업캐스팅(UpCasting) - 자동으로 이루어짐
부모 → 자식 : 다운캐스팅(DownCasting) - 명시해주어야 함

Parent poly = new Child(); //⭐️ 자동 형 변환
poly.parentMethod();
//poly.childMethod -> 컴파일 오류 발생

위의 예제처럼 부모가 자식 클래스를 쓸 수 있었던 이유는 ✨업캐스팅✨ 덕분이었다.

위의 예제의 업캐스팅은 부모의 타입으로 데이터를 다룰 수 있지만, 자식 클래스의 고유 기능은 사용 불가하다.
부모클래스가 자식 클래스를 참조해 자식의 기능도 사용하고 싶다면 ✨다운캐스팅✨을 알아야한다

🔄 다운캐스팅

: 다운캐스팅으로 자식 클래스의 고유 메서드를 사용 가능하다

Parent poly = new Child(); 
poly.parentMethod();
//⭐️ 다운캐스팅 (부모 Parent -> 자식 Child)
Child child = (child) poly;
child.childMethod //⭐️ 자식 클래스의 기능 활용 가능함.

instanceof

잘못된 다운 캐스팅을 컴파일 단계에서 감지할 수 없기 때문에,
instanceof를 활용하는 것이 좋다.
: 객체가 특정 클래스나 인터페이스의 인스턴스인지 확인해줌

Parent poly = new Child(); 
poly.parentMethod();
//⭐️ 다운캐스팅 (부모 Parent -> 자식 Child)
Child child = (child) poly;
child.childMethod(); //⭐️ 자식 클래스의 기능 활용 가능함.
if (poly instanceof Child){
	Child child = (child) poly;
    child.childMethod();
} else {
	System.out.println("다운캐스팅이 잘못됐어요");
    }
    

3. 다형성의 장점

이렇게 개념만 봐서는 왜 다형성을 써야하지...?라고 생각이 들었다.
예시를 보면서 장점을 알아보자

고양이와 강아지의 특성을 출력하고 싶을때, 다형성을 사용하면 코드의 길이를 줄이고 중복없이 깔끔하게 적을 수 있다.

public class Main {
    public static void main(String[] args) {
        Animal[] animals = {new Cat(), new Dog()};
        for (Animal animal : animals) {
            animal.makeSound();
        }
    }
}
profile
@lim_128

0개의 댓글