다형성
class Animal {
public void sound(){
System.out.println("동물 울음 소리");
}
}
// Cat, Cow, Dog 클래스를 생성해서 Animal을 상속하고 sound() 메소드를 오버라이딩한다.
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
Cow cow = new Cow();
//오버라이딩 된 메소드가 우선권을 갖고 호출
soundAnimal(dog);
soundAnimal(cat);
soundAnimal(cow);
}
private static void soundAnimal(Animal animal) {
System.out.println("동물 소리 테스트 시작");
animal.sound();
System.out.println("동물 소리 테스트 종료");
}
}
- soundAnimal() 메소드에서 다형적 참조를 이용했다.
- Dog, Cat, Cow 클래스는 Animal 클래스의 자식 클래스이며 sound() 를 오버라이딩 한 상태다.
Animal(부모) 타입에서 자식 인스턴스를 참조할 수 있기 때문에 main() 메소드의 soundAnimal() 매개 변수로 Animal 타입으로 지정했다. (중복 제거) - soundAnimal() 에서 animal.sound() 를 호출하면 먼저 자신의 타입인 Animal 타입에서 sound() 를 찾지만 자식 클래스 중 sound() 를 오버라이딩 한 메소드가 있다면 그 메소드가 우선권을 갖고 호출된다.
결국 자식 클래스(Cat, Dog, Cow)에서 오버라이딩 한 sound() 가 호출된다.
- Dog, Cat, Cow 클래스는 Animal 클래스의 자식 클래스이며 sound() 를 오버라이딩 한 상태다.
- 배열은 같은 타입의 데이터를 나열할 수 있기에 Animal 타입의 자식 클래스들도 다형적 참조를 통해 Animal 타입 배열에 저장할 수 있다.
- 새로운 기능이 추가되었을 때 변하는 부분을 최소화 하는 것이 잘 작성된 코드!
- 위 예시의 문제점
- 부모 클래스인 Animal은 추상적인 개념 (동물)이기에 직접 인스턴스를 생성해서 사용할 일이 없는데 인스턴스는 생성할 수 있기에 실수로 인스턴스를 생성해서 사용하는 경우 제대로 된 기능을 하지 못한다.
- 부모 클래스인 Animal을 상속받는 자식 클래스에서 sound()를 오버라이딩하지 않는다면 원하는 결과가 나오지 않는다.
- 이러한 문제들에 대해 제약을 만들고 해결한 개념이 추상 클래스와 추상 메소드다.
추상 클래스 / 추상 메소드
public abstract class Animal {...}
- 추상 클래스 : 부모 클래스는 제공하지만, 실제 생성되면 안되는 클래스로 추상적인 개념을 제공한다.
- 인스턴스를 생성하지 못하는 제약이 있지만 상속을 목적으로 사용되고 부모 클래스 역할을 담당한다.
- 클래스 선언 시 abstract class로 선언한다.
- ex) 코끼리, 개, 고양이는 실제로 존재하지만 동물이라는 추상적인 개념은 존재하지 않는다.
public abstract void sound();
- 추상 메소드 : 부모 클래스를 상속받는 자식 클래스가 반드시 오버라이딩해야 하는 메소드를 부모 클래스에 정의할 수 있다.
- 추상적인 개념을 제공하는 메소드로 실체가 존재하지 않고 메소드 바디(내용)가 없다.
- 메소드 앞에 abstract 키워드를 사용한다.
- 추상 메소드가 하나라도 있는 클래스는 추상 클래스로 선언되야 한다!!
- 추상 메소드는 상속 받는 자식 클래스가 반드시 오버라이딩(구현)해서 사용해야한다!!
- 자식 클래스 중 추상 메소드를 오버라이딩(구현)하지 않으면 추상 메소드 그대로 남아있기 때문에 자식 클래스도 추상 클래스가 되어야 한다.
- 추상 클래스 내부에 일반 메소드가 존재할 수 있으며 이 경우 자식 클래스에서 반드시 오버라이딩(구현)할 필요는 없다.
- 순수 추상 클래스 : 모든 메소드가 추상 메소드인 추상 클래스
- 실행하는 로직을 전혀 가지고 있지 않으며 다형성만을 위한 부모 타입으로 껍데기 역할을 제공한다.
- 인스턴스를 생성할 수 없다.
- 상속받은 자식 클래스는 모든 메소드를 오버라이딩 해야한다.
- 다형성을 위해서 사용된다.
- 자바에서는 순수 추상 클래스를 더 편리하게 사용하도록 인터페이스라는 기능을 제공한다.
인터페이스
- 인터페이스는 순수 추상 클래스의 특징을 가지면서 편의 기능이 추가됐다.
- 인스턴스를 생성할 수 없다.
- 상속 시 모든 메소드를 오버라이딩 해야한다.
- 다형성을 위해서 사용된다.
- 인터페이스의 모든 메소드는 public, abstract 이다.
- 메소드에 public abstract를 생략할 수 있으며 생략하는 것을 권장한다.
- 인터페이스는 다중 구현(다중 상속)을 지원한다.
- 멤버 변수는 public, static, final이 모두 포함되었다고 간주된다. 생략하는 것을 권장한다.
- 즉, 상수만 정의할 수 있다.
- 클래스는 상속이라는 표현을 인터페이스는 구현이라는 표현을 사용한다.
- 인터페이스를 구현할 때에도 extends 대신 implements를 사용한다.
- 다중 구현 시 implements 뒤에 ,로 구분해서 인터페이스를 명시한다.
- 클래스 상속과 인터페이스 구현을 동시에 하는 경우 extends를 먼저 써주고 그 다음 implements를 써야한다.
- UML 표기 시 상속은 실선을 사용해 표현하며 구현은 점선을 사용한다.
- 인터페이스를 구현할 때에도 extends 대신 implements를 사용한다.
- 상속 vs 구현
- 상속은 부모의 기능을 물려받는 것이 목적
- 인터페이스는 모든 메소드가 추상 메소드이기에 물려받을 기능이 없고 오히려 인터페이스에 정의된 모든 메소드를 오버라이딩함으로 구현해야하므로 구현이라는 표현을 사용한다.
- 인터페이스는 메소드 이름만 있는 설계도이며 설계도가 작동하는 방법은 하위 클래스에서 모두 구현해야한다.
- 클래스, 추상 클래스, 인터페이스의 코드, 메모리 구조상 모두 같다.
- 자식 클래스 인스턴스 생성 시 상위 클래스의 인스턴스도 메모리 상에 생성되는 부분
- 인터페이스를 사용하는 이유?
- 제약 - 인터페이스를 구현하는 곳에서 인터페이스의 메소드를 반드시 구현하라는 제약을 주는 것.
- 추상 클래스는 메소드를 구현할 수도 안할 수도 있기에 제약이 없지만 인터페이스는 무조건 모든 메소드를 구현하라고 제약을 하기 때문에 더 강제성을 띈다.
- 다중 구현 - 상속은 부모 클래스 하나만을 지정할 수 있지만 구현은 인터페이스 여러 개를 다중 구현할 수 있다.
- 클래스를 다중 상속 시 다이아몬드 문제가 발생할 수 있으나 인터페이스에는 기능이 없고 메소드 이름만 있기에 여러 인터페이스의 메소드가 겹치더라도 어느 메소드를 호출하든 크게 문제가 되지 않기에 다중 구현이 가능하다.
- 제약 - 인터페이스를 구현하는 곳에서 인터페이스의 메소드를 반드시 구현하라는 제약을 주는 것.
- 인터페이스에 예외적으로 메소드를 구현하는 경우
- Java 8부터 default 메소드를 사용해서 인터페이스에 메소드를 구현할 수는 있지만 예외적으로 아주 특별한 경우에만 사용한다.
- Java 9부터 private 메소드를 통해 인터페이스에 메소드 구현하는 것도 마찬가지다.
- 모두 하위 호환성때문에 생겨난 기능으로 지금은 고려하지 않는 것이 좋다....
출처:[인프런 김영한 실전 자바 - 기본편]
김영한의 실전 자바 - 기본편 강의 | 김영한 - 인프런
김영한 | 실무에 필요한 자바 객체 지향의 핵심 개념을 예제 코드를 통해 쉽게 학습합니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문
www.inflearn.com
'Java > [인프런 김영한 실전 자바 - 기본편]' 카테고리의 다른 글
[인프런 김영한 실전 자바 - 기본편] 다형성과 설계 (0) | 2024.07.17 |
---|---|
[인프런 김영한 실전 자바 - 기본편] 다형성1 (0) | 2024.07.16 |
[인프런 김영한 실전 자바 - 기본편] 상속 (0) | 2024.07.16 |
[인프런 김영한 실전 자바 - 기본편] final (0) | 2024.07.16 |
[인프런 김영한 실전 자바 - 기본편] 자바 메모리 구조와 static (0) | 2024.07.16 |