728x90
Java에서 다형성을 지원하는 방법으로는 메서드 오버로딩과 오버라이딩이 있다
오버로딩(Overloading)
- 메서드 오버로딩과 생성자 오버로딩이 있는데, 이들은 실제로 적용되는 것은 동일하다
- 메서드의 이름은 같고 매개변수의 갯수나 타입이 다른 함수를 정의하는 것
- 리턴값만 다르게 갖는 오버로딩은 작성할 수 없다
- 기존에 없던 새로운 메서드를 정의하는 것
오버로딩 조건
1. 매개변수의 개수가 달라야 한다
// 매개변수 개수가 다른 경우
public int overloadTest() {
return 0;
}
public int overloadTest(String test) {
return 1;
}
2. 매개변수의 타입이 달라야 한다
// 매개변수 타입이 다른 경우
public int overloadTest(String test) {
return 1;
}
public int overloadTest(int test) {
return 1;
}
📌 즉, 오버로딩은 매개변수의 차이로만 구현이 가능하다!
오버로딩의 특징
- 오버로딩된 각 메소드의 접근 제어자를 자유롭게 지정할 수 있다
- 오버로딩된 각 메서드의 접근 제어자를 public, default, protected, private으로 다르게 지정해도 상관없다!
- 그러나 같은 매개변수 개수와 타입을 가지면서 접근 제한자만 다르게 한다고 오버로딩되지는 않는다!
- 또한 매개변수는 같고 반환 타입만 다른 경우에도 오버로딩이 성립되지 않는다!
- 메소드 이름이 같아야 한다
- 리턴형은 같아도 되고 달라도 된다
- 파라미터 개수가 달라야 한다
- 만약 파라미터 개수가 같을 경우, 파라미터 타입이 달라야 한다
- 메소드의 리턴 타입만 다른 경우 오버로딩 불가능!
오버로딩의 장점
- 한 개의 클래스 안에서 오버로딩의 조건에 따라 같은 이름의 메서드를 정의할 수 있다
- 비슷한 기능을 가진 메서드들의 이름을 지을 때, 각 메서드 별로 이름을 구별하지 않고, 하나의 이름으로 통일성 있게 정의할 수 있다 -> 메서드 이름 절약 가능
오버라이딩(Overriding)
- 상위 클래스의 메서드를 하위 클래스가 변경(재정의)하는 것
- 메서드의 이름은 물론 파라미터의 갯수나 타입도 동일해야 하며, 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하기 위해 사용된다
- 상속 받은 메서드의 내용만 변경하는 것으로, 쉽게 보면 덮어쓴다고 생각하면 된다
오버라이딩의 조건
1. 매개 변수가 같아야 한다
2. 리턴 타입이 같아야 한다
[예시]
public class Parent {
public void overridingTest() {
System.out.println("부모 메서드의 내용");
}
}
// 오버라이딩
class Child extends Parent {
@Override
public void overridingTest() {
System.out.println("상속받은 부모 메서드의 내용을 수정하여 자식 메서드의 내용으로 재사용");
}
}
위처럼 오버라이딩은 메서드의 선언부는 부모의 메서드와 일치하며, 메서드의 내용만 재정의하여 사용하는 것이다
오버라이딩의 특징
- 오버라이드 하고자 하는 메소드가 상위 클래스에 존재해야 한다
- 메소드의 이름, 파라미터 개수, 파라미터 타입, 메소드 리턴형이 모두 같아야 한다
- 상위 메소드와 동일하거나 내용이 추가되어야 한다
- 상위 클래스의 메서드보다 접근 제어자를 더 좁은 범위로 변경할 수 없다
- 만약 부모 클래스의 접근 제어자가 default인 경우, 자식 클래스들은 더 넓은 범위의 접근 제어자인 default, protected, public 중 하나만 사용이 가능하다
- 상위 클래스의 메서드보다 더 큰 범위의 예외를 선언할 수 없다
- 부모 클래스에서 어떤 예외를 thorws 한다고 하면, 자식 클래스에서는 그 예외보다 더 큰 범위의 예외를 throws 할 수 없다
- 상위 클래스의 static 메서드는 클래스에 속하는 메서드이기 때문에 상속되지 않고, 오버라이드 또한 불가능하다!
- static 메소드는 런타임 시에 생성되는 것이 아닌, 컴파일 시에 생성되어 메모리에 적재되기 때문에 런타임 시에 해당 메서드를 구현한 실체 객체를 찾아가서 호출하게 된다
- 따라서 static 메서드에 대해서는 다형성이 적용되지 않는다
- 또한 부모클래스의 메소드를 static 메소드로 바꾸는 것도 불가능하다
- final이 지정된 메소드 또한 오버라이드가 불가능하며, private 접근 제어자를 갖는 메서드는 상속 자체가 불가능하기 때문에 오버라이드가 성립되지 않는다
- final의 경우 하위 클래스가 해당 메서드를 재정의할 수 없도록 하기 위해 사용된다
- implements를 통해 인터페이스를 가져와서 인터페이스에 정의된 메소드를 @Override 어노테이션을 통해 오버라이딩해서 재정의하는데, 이 때 interface의 메서드를 오버라이드해서 구현하는 경우 반드시 public 접근 제어자를 사용해야 한다
💡 @Override 어노테이션이 없어도 오버라이딩이 가능한데 해당 어노테이션을 사용하는 이유?
- @Override는 시스템에서 오버라이딩한 메서드라고 알리는 역할로, 오버라이딩이 잘못된 경우 경고를 준다
- @Override 어노테이션이 적용되지 않은 상태에서는 전에 오버라이드 한 메서드가 업데이트 이후 그냥 추가적인 메서드로 인식되어 컴파일 오류가 발생하지 않는다
- 이 때 @Override 어노테이션을 적용함으로써 의도적으로 컴파일 오류를 일으켜 작동방식이 바뀌는 것을 대비할 수 있다
- 또한 @Override를 표시함으로써 코드 리딩 시에 해당 메서드가 오버라이딩하였다는 것을 쉽게 파악할 수 있다는 장점이 있다
💡 오버로딩 vs 오버라이딩
- 오버로딩 : 같은 이름의 메서드(기존에 없던 새로운 메서드)를 생성하여 사용하는 것 / 확장
- 오버라이딩 : 부모로부터 상속받은 메서드를 재정의(내용만 변경)하여 사용하는 것 / 재정의
참고)
https://nobacking.tistory.com/56
https://wildeveloperetrain.tistory.com/110
https://hyoje420.tistory.com/14
728x90
'야미스터디 > Java' 카테고리의 다른 글
[Java] 스네이크, 카멜, 파스칼 케이스 📌 (0) | 2022.09.03 |
---|---|
[Java] 인터페이스와 추상클래스 📌 (0) | 2022.08.18 |
[Java] Mutable vs Immutable 📌 (0) | 2022.08.07 |
[Java] 접근 제한자 / 생성자 / SOLID 📌 (0) | 2022.08.06 |
[JAVA] static 변수 (0) | 2022.07.26 |
댓글