[JAVA]김영한의 실전 자바 ; 다형성3, 추상 클래스

선뀰·2024년 1월 8일
0

JAVA

목록 보기
19/25

새로운 동물이 추가 되었을 때 변하는 부분을 최소화 하는 것이 잘 작성된 코드이다.
코드에서 변하는 부분과 변하지 않는 부분을 명확하게 구분하는 것이 좋다.
변경 범위가 많을 경우 코드가 지저분 해진다.

  • 남은 문제
  1. Animal 클래스를 생성할 수 있는 문제
    개, 고양이, 소가 실제 존재하는 것은 당연하지만, 동물이라는 추상적인 개념이 실제로 존재하는 것은 이상하다. 이 클래스는 다형성을 위해서 필요한 것이지 직접 인스턴스를 생성해서 사용할 일은 없다.
  1. Animal 클래스를 상속 받는 곳에서 sound() 메서드 오버라이딩을 하지 않을 가능성이 있다.

추상 클래스

동물(Animal)과 같이 부모 클래스는 제공하지만, 실제 생성되면 안되는 클래스를 추상 클래스라 한다.
추상적인 개념을 제공하는 클래스이다. 실체인 인스턴스가 존재하지 않는다. 대신에 상속을 목적으로 사용되고, 부모 클래스 역할을 담당한다.

abstract calss AbstractAnimal {...}

  • 추상 클래스는 클래스를 선언할 때 앞에 추상이라는 의미의 abstract 키워드를 붙여주면 된다.
  • 추상 클래스는 기존 클래스와 같다. new AbstractAnimal()와 같이 직접 인스턴스를 생성하지 못하는 제약이 있다.

추상 메서드

부모 클래스를 상속 받는 자식 클래스가 반드시 오버라이딩 해야 하는 메서드를 부모 클래스에 정의할 수 있다. 이것을 추상 메서드라 한다. 추상 메서드는 이름 그대로 추상적인 개념을 제동하는 메서드이다. 따라서 실체가 존재하지 않고, 메서드 바디가 없다.

public abstract void sound();

  • 추상 메서드가 하나라도 있는 클래스는 추상 클래스로 선언해야 한다.
    추상 메서드는 메서드 바디가 없다. 따라서 작동하지 않는 메서드를 가진 불완전한 클래스이다.
    따라서 직접 생성하지 못하도록 추상 클래스로 선언해야 한다.

  • 추상 메서드는 상속 받는 자식 클래스가 반드시 오버라이딩 해서 사용해야 한다.
    추상 메서드는 자식 클래스가 반드시 오버라이딩 해야 하기 때문에 메서드 바디 부분이 없다.
    바디 부분을 만들면 컴파일 오류가 발생한다.
    오버라이딩 하지 않으면 자식도 추상 클래스가 되어야 한다.

  • 추상 메서드는 기존 메서드와 완전히 같다. 다만 메서드 바디가 없고, 자식 클래스가 해당 메서드를 반드시 오버라이딩 해야 한다는 제약이 추가된 것이다.

  • 오버라이딩 하지 않을 경우
    public abstract class AbstractAnimal처럼 abstract를 사용해야 한다.

public abstract class AbstractAnimal {
    public abstract void sound();
    // 추상 메서드는 자식 클래스가 반드시 오버라이딩 해야 한다.

}
  • 오버라이딩 선언 할 경우
    abstract를 사용하지 않아도 된다.
public class  HelloAnimal extends AbstractAnimal{
    @Override
    public void sound() {
        // 오버라이딩 해야 한다.  오버라이딩을 하면 상관 없지만

    }
}

추상 클래스는 제약이 추가된 클래스이다. 메모리 구조, 실행 결과 모두 동일하다.
추상 클래스 덕분에 실수로 Animal 인스턴스를 생성할 문제를 방지해준다.
추상 메서드를 사용하여 새로운 동물의 자식 클래스를 만들 때 실수로 sound()를 오버라이딩 하지 않을 문제를 방지해준다.

추상 클래스 2 = 옛날 용어이다

  • 순수 추상 클래스 : 모든 메서드가 추상 메서드인 추상 클래스
    상속하는 자식 클래스도 모두 오버라이딩 해줘야 한다.
public abstract class AbstractAnimal {
  public abstract void sound();
  public abstract void move();
}
  • 인스턴스를 생성할 수 없다.
  • 상속시 자식은 모든 메서드를 오버라이딩 해야 한다.
  • 주로 다형성을 위해 사용된다.

인터페이스

자바는 순수 추상 클래스를 더 편리하게 사용할 수 있는 인터페이스라는 기능을 제공한다.
인터페이스는 구현이다. 상속이라 하지 않고, 구현이라고 한다.

  • 순수 추상 클래스
public abstract class AbstractAnimal {
  public abstract void sound();
  public abstract void move();
}
  • 인터페이스
public interface InterfaceAnimal {
	public abstract void sound();
    public abstract void move();
}
  • 인터페이스 public abstract 키워드 생략 가능
public interface InterfaceAnimal {
	void sound();
    void move();
}
public class Dog implements InterfaceAnimal{
    @Override
    public void sound() {
        System.out.println("멍멍");
    }

    @Override
    public void move() {
        System.out.println("개 이동");
    }
}

인터페이스는 순수 추상 클래스와 같다. 약간의 편의 기능이 추가된다.

  • 인터페이스의 메서드는 모두 public, abstract이다.
  • 메서드에 public abstract를 생략할 수 있다. 참고로 생략이 권장된다.
  • 인터페이스는 다중 구현(다중 상속)을 지원한다.

인터페이스와 멤버 변수

public interface InterfaceAnimal {
	public static final int MY_PI = 3.14;
    // int MY_PI = 3.14;로 주로 사용한다.
}

인터페이스에서 멤버 변수는 public, static, final 이 모두 포함되어 있다고 간주한다.
상수 정도는 정의할 수 있다.

인터페이스 구현(상속)이 된다.
인터페이스를 상속 받을 때는 implements를 사용한다.
public class Dog implements InterfaceAnimal {

}

클래스, 추상 클래스, 인터페이스는 모두 똑같다.

  • 클래스, 추상 클래스, 인터페이스는 프로그램 코드, 메모리 구조상 모두 똑같다.
    자바에서는 .class로 이루어진다. 인터페이스를 작성할 때도 .java에 인터페이스를 정의한다.
  • 인터페이스는 순수 추상 클래스와 비슷하다고 생각하면 된다.

상속 vs 구현

부모 클래스의 기능을 자식 클래스가 상속 받을 때 클래스는 상속 받는다고 하지만, 인터페이스를 구현한다고 표현하면 된다. 사실 자바에서는 상속과 구현은 똑같다. 동일하게 작동한다.

  • 상속은 부모의 기능을 물려 받는다. 하지만 인터페이스는 모든 메서드가 추상 메서드이다.
    따라서 물려 받을 수 있는 기능이 없고, 인터페이스에 정의한 모든 메서드를 자식이 오버라이딩 해서 기능을 구현해야 한다. 따라서 구현한다고 표현한다.

인터페이스를 사용해야 하는 이유

모든 메서드가 추상 메서드인 경우 순수 추상 클래스를 만들어도 되고, 인터페이스를 만들어도 된다. 인터페이스를 굳이 사용하는 이유가 있다.

  • 제약 : 인터페이스를 만드는 이유는 구현하는 곳에서 인터페이스의 메서드를 반드시 구현하라는 규약을 주는 것이다.

  • 다중 구현 : 자바에서 클래스 상속은 부모를 하나만 지정할 수 있다. 반면에 인터페이스는 부모를 여러명 두는 다중 구현(다중 상속)이 가능하다.

추상클래스

추상클래스는 추가된 기능을 자식 클래스에서 구현하지 않을 수 있다.

public abstract class AbstractAnimal {
public abstract void sound();
// 추상 메서드는 자식 클래스가 반드시 오버라이딩 해야 한다.
public abstract void move();// 모든 것이 다 추상 메서드가 된다.

public void hello() {
    System.out.println("안녕하세요. 동물입니다.");
}

}

하지만 인터페이스는 모든 메서드가 추상 메서드이다.

다중 구현

  • 자바가 다중 상속을 지원하지 않는 이유
    자바는 다중 상속을 지원하지 않는다. 그래서 extend 대상은 하나만 선택할 수 있다. 부모를 하나만 선택할 수 있다는 뜻이다. 물론 부모가 또 부모를 가지는 것은 괜찮다.
profile
공부 기록

0개의 댓글