Goal
- 다형성에 대해 알아본다
- 오버라이딩에 대해 알아본다
- 오버로딩에 대해 알아본다
- 오버라이딩과 오버로딩이 동시에 발생한 경우는?
- 오버라이딩과 오버로딩을 사용한 코드 예시를 살펴본다.
객체지향의 특성 참고
[객체지향의 원리와 이해 3] 자바와 객체 지향
객체지향의 4대 특성 - 캡!상추다 캡슐화 (Encapsultation): 정보 은닉(information hiding) 상속 (Inheriance) 재사용 추상화 (Abstaction) : 모델링 다형성 (Polymorphism) : 사용 편의 클래스 vs. 객체 = 붕어빵틀 vs.붕
dev-rosiepoise.tistory.com
다형성(Polymorphism)이란?
객체지향의 4대 특성중 하나로 사용편의성을 의미하며, 하나의 객체가 여러가지 타입을 가질 수 있는 것이다.
다형성을 구현하는 방법 2가지
- 오버라이딩
- 오버로딩
오버라이딩(overriding) 이란?
같은 메서드이름, 같은 인자 목록으로 상위 클래스의 메서드를 재정의하는 것이다
왜 or 언제 오버라이딩을 사용하는가?
상위 클래스의 메소드의 결과를 다르게 사용하고 싶을 때(같아도 됨) 사용한다. 이때, 오버라이딩을 하지 않으면 비슷한 새로운 메소드들을 선언해야하고 이는 중복코드가 많아지고 유지보수의 용이성이 떨어진다.
특징
- 메서드 이름이 동일
- 파라미터 형태 동일
- 리턴 형태 동일
- 접근 제한자는 부모 클래스보다 더 범위가 넓게 (private < default < protected < public) 사용되어야 하고, 부모 클래스의 메소드보다 접근 제어자를 더 좁은 범위로 변경할 수없다
- 부모 클래스의 메소드보다 더 큰 범위의 예외를 선언할 수 없다
오버라이딩의 우선순위
- 오버라이딩된 메소드는 인스턴스의 실제 타입에 따라 결정됨
- 따라서, 상위 클래스의 메소드가 하위 클래스에 의해 오버라이딩된 경우, 인스턴스의 타입에 맞는 하위 클래스의 메소드가 호출됨
- 상속 관계에서 메소드 호출 시, 해당 메소드가 오버라이딩되어 있다면, 오버라이딩된 메소드가 우선적으로 호출됩니다.
오버로딩(overrloading) 이란?
같은 메서드이름, 다른 인자 목록으로 다수의 메소드를 중복 정의(확장)하는 것
왜 or 언제 오버로딩을 사용하는가?
같은 역할을 하는 메소드는 같은 메소드 이름을 가져야하고, 매개변수만 다르게 하는 것이 오버로딩의 모토이다 ex. System.out.println()
특징
- 메서드 이름이 동일
- 파라미터 형태 다름
- 파라미터 순서도 달라야함
- 리턴 형태 상관 없음
오버로딩의 우선순위
- 오버로딩된 메소드 호출 시, 매개변수의 형태를 기준으로 호출 대상 메소드를 결정
- 호출하려는 메소드와 인자의 데이터 타입이 정확히 일치하는 경우 해당 메소드가 우선적으로 호출됨
- 일치하는 메소드가 없는 경우, 자동 형변환이 가능한 메소드 중에서 가장 '근접한' 타입으로 형변환되는 메소드가 호출됩니다.
오버라이딩과 오버로딩이 동시에 발생하면 어떻게 될까?
메소드 호출 시, 메소드의 실제 동작을 가장 정확하게 결정하는 것이 주 목적이기 때문에 오버라이딩이 먼저 고려되며 이후에 오버로딩이 고려된다. 호출하려는 메소드가 오버라이딩된 메소드인 경우, 실제 인스턴스의 타입을 기반으로 오버라이딩된 메소드가 선택됩니다.
이때 메소드의 매개변수 타입과 관련해서 오버로딩이 적용되더라도, 먼저 오버라이딩된 메소드가 우선적으로 선택됩니다. 오버라이딩된 메소드가 해당 시그니처와 일치하지 않는다면 오버로딩된 메소드가 고려되어 호출될 수 있다.
오버라이딩과 오버로딩을 사용한 코드
상위 클래스 코드
public class Animal2 {
public String animalName;
public void showName(){
System.out.printf("안녕 나는 %s야. 반가오\n", animalName);
}
}
하위 클래스 코드
public class Penguin extends Animal2{
public String habitat;
public void showHabitat(){
System.out.printf("%s는 %s에 살아\n", animalName, habitat);
}
// 오버라이딩
@Override
public void showName() {
System.out.println("내 이름은 알아서 뭐하시게요!");
}
// 오버로딩
public void showName(String yourName){
System.out.printf("%s 안녕, 나는 %s라고 해 \n", yourName, animalName);
}
}
- 오버라이딩
- @Override 표기 생략가능
- Animal2클래스의 showName()를 재정의 : 메소드 이름 동일, 매개 변수 타입 동일, 리턴 형태 동일
- 오버로딩
- showName()를 중복정의 : 메소드 이름 동일, 다른 매개 변수 타입, 리턴 형태 상관없음
public class Driver {
public static void main(String[] args){
Penguin pororo = new Penguin();
pororo.animalName="뽀로로";
pororo.habitat="남극";
pororo.showName();
pororo.showName("초보람보");
pororo.showHabitat();
Animal2 pingu = new Penguin();
pingu.animalName="핑구";
pingu.showName();
}
}
결과
내 이름은 알아서 뭐하시게요!
초보람보 안녕, 나는 뽀로로라고 해
뽀로로는 남극에 살아
내 이름은 알아서 뭐하시게요!
참고
자바의 신 by 이상민
스프링 입문을 위한 자바 객체지향과 원리
https://steady-coding.tistory.com/540
'JAVA > about java' 카테고리의 다른 글
[type] 자료형, 기본 자료형 (Primitive type) vs 참조 자료형(Reference type) (0) | 2023.08.21 |
---|---|
[variables] 지역변수, 클래스변수, 인스턴스 변수 (0) | 2023.08.20 |
[Class Loader] 클래스 로딩 시점 / 클래스 로딩 / 클래스 초기화 (0) | 2023.07.02 |
[Thread] 쓰레드 (0) | 2023.05.10 |
[static] satic 블록, static 변수와 static 메서드 (0) | 2023.05.03 |