* 오버로딩과 오버라이딩은 용어 때문에 헷갈리는 경우가 많은데 오버로딩과 오버라이딩은 크게 관련이 없다.
오버로딩과 오버라이딩
오버로딩 (overloading)
오버로딩이란 한 클래스 내에 매개변수의 수와, 매개변수의 타입이 다른 동일한 이름의 메서드가 여러 개 정의된 것을 의미한다.
public class OverloadingEx {
public static void main(String args[]) {
PrintlnByType result = new PrintlnByType();
result.println("string");
result.println(123);
result.println(true);
// string은 String
// 123은 int
// true은 boolean
}
}
class PrintlnByType {
void println (String str) {
System.out.println(str+"은 String");
}
void println (int _int) {
System.out.println(_int+"은 int");
}
void println(boolean _boll) {
System.out.println(_boll+"은 boolean");
}
}
클래스 PrintlnByType는 매개변수 타입이 다르고 동일한 메서드명으로 되어 있는 여러 개의 메서드를 가지고 있는데, 이를 오버로딩이라 한다. 오버로딩의 조건으로 첫째는 메서드명이 동일해야 한다는 점이고, 둘째는 매개변수의 갯수나 타입이 서로 달라야 한다는 것이다.
* 가변인자? ex)String...
가끔씩 코드를 보면 매개변수로 String... 등과 같이 [타입]... 형식으로 되어 있는 것을 볼 수 있다. 이러한 형식의 매개변수를 가변인자라 하는데 가변인자는 매개변수로, 해당 타입이 몇 개가 오게 될 지 명확하지 않은 경우에 사용된다. 매개변수의 타입을 가변인자로 주게 되면, 해당 매개변수에 몇 개가 오던지 처리가 가능하며, 심지어는 매개변수에 대해 인자를 넣지 않아도 에러가 발생하지 않는다.
* 가변인자를 사용시 다른 매개변수와 구분이 어려워질 수 있기 때문에 가능한 가변인자가 사용된 메서드의 경우에는 오버로딩을 하지 않는 것이 좋다.
오버라이딩
오버라이딩이란 상속관계에서 나타나는 것으로, 상위 클래스를 상속받은 하위 클래스에서 부모클래스에서 정의된 메서드를 재정의하는 것을 의미한다.
class Person {
public void sayMe() {
System.out.println("나는 사람입니다.");
}
}
class Teacher extends Person {
public void sayMe() {
System.out.println("나는 선생님입니다.");
}
}
class Student extends Person {
}
public class OverRidingEx {
public static void main(String args[]) {
Person me1 = new Person();
Teacher me2 = new Teacher();
Student me3 = new Student();
me1.sayMe(); // 나는 사람입니다.
me2.sayMe(); // 나는 선생님입니다.
me3.sayMe(); // 나는 사람입니다.
}
}
위의 코드를 보면 상위클래스인 Person은 하위클래스 Teacher와 Student가 상속받았는데, 상위클래스에 정의된 sayMe() 메서드를 Teacher에서는 오버라이딩이 이루어졌고, Student에서는 오버라이딩이 이루어지지 않았다. main함수에서 각 클래스들의 sayMe를 출력하여 확인해보면 Teacher 인스턴스의 경우에는 sayMe()메서드가 오버라이딩되어 "나는 선생님입니다."를 출력하고, Student 인스턴스의 경우에는 기존에 상위 클래스에 정의된 대로 "나는 사람입니다."를 출력하는 것을 확인할 수 있다.
오버라이딩의 경우 매개변수와 메서드명은 물론 반환타입도 동일해야 하위클래스에서 제대로 오버라이딩이 이루어진다. (sayMe() 메서드의 경우 매개변수가 없고, 반환타입 void로 일치하는 것을 확인할 수 있다.)
* super
상위클래스에서 선언된 멤버변수와 하위클래스에서 선언된 멤버변수명이 같을 때에 해당 멤버변수를 구별하기 위해 사용된다. 하위클래스에서 super.[멤버변수명], super.[메서도명] 이와 같은 식으로 상위클래스의 멤버변수와 메서드에 접근한다. 또한 super()는 상위클래스의 생성자 함수 호출시에 사용된다. (즉 상위클래스에 선언된 멤버변수 초기화를 위해 사용)
- super()는 사용시에 생성자의 첫 줄에서 사용되어야 한다. 상속관계에 있는 하위클래스의 생성자함수에서 super();로 상위클래스의 생성자 함수를 호출하지 않는 경우에는 컴파일러에 의해 자동으로 super()가 있는 것처럼 인식되어 실행된다.
오버라이딩 규칙
1. 하위 클래스에서 상위 클래스에 정의된 메서드를 오버라이딩 하는 경우, 해당 메서드와 매개변수, 반환타입, 메서드명이 같아야 한다.
2. 접근 제어자는 상위클래스의 메서드에 선언된 범위보다 작아질 수 없다.
ex) 상위 클래스 메서드의 접근제어자가 protected라면, 하위 클래스에서 해당 메서드를 오버라이딩 하는 경우에는 protected보다 큰 범위인 public또는 protected로 선언되어야 한다.
3. 하위 클래스에서 메서드를 오버라이딩 할 때, 상위 클래스의 오버라이딩 되는 메서드보다 더 많은 예외를 선언할 수 없다.
* 접근제어자 범위 private < default < protected < public
- private : 클래스 자기 자신 안에서만 접근 가능
- default : 같은 패키지 내에서는 접근 가능, (접근제어자를 명시해주지 않는 경우 기본값이다.)
- protected : 같은 패키지 내에서 접근 가능하고, 추가로 상위 클래스를 상속 받은 하위 클래스에서는 접근 가능(같은 패키지가 아니여도 가능하다.)
- public : 어디서나 접근 가능하다.
출처
자바의 정석 (남궁성 지음)
'JAVA' 카테고리의 다른 글
[ Java ] - 상속 (instanceOf / 멤버변수가 같을 때 ) (0) | 2023.01.02 |
---|---|
[ Java ] - 생성자 (0) | 2022.12.30 |
[ Java ] - 클래스 / 객체 / 인스턴스 (인스턴스의 생성과 사용법) (0) | 2022.12.28 |
[ Java ] - 변수의 타입(기본형 / 참조형) * 자바메모리 구조 (0) | 2022.12.25 |
[ Java ] - 어노테이션(annonation) (0) | 2022.12.24 |