이번 스터디에서는 메소드 오버라이딩에 대해 다뤄보려 한다.
다른말로 하면 "함수덮어쓰기" 정도로 표현할 수 있겠다.
바로 소스와 함께 알아보자.
class Parent {
final int number;
Parent(int number) : this.number = number;
//Function 함수
//Method
int calculate() {
return this.number * number;
}
}
int형 상수 number값을 가지고, calculate 라는 기능을 가진 함수를 가진 클래스 하나를 선언한다.
※ 클래스 안에 선언된 것들을 보통 메소드라고 부르고, 클래스에 종속되지 않고,
밖에 별도로 선언된 것들을 함수라고 하는데 사실 이것도 분명히 나뉘는것은 아니다.
"메소드 = 함수" 동의어로 생각하면 되겠다.
다음은 위 Parent클래스를 상속받는 자식클래스 하나를 선언하자.
class Child extends Parent {
Child(
int number,
) : super(number = number);
@override
int calculate(){
//부모클래스의 calculate함수를 자식클래스에서 덮어쓰기
return this.number + this.number;
}
}
여기서 알고 넘어가야 할것들
1. 해당 Child클래스는 Parent클래스를 상속받는다.
2. @override는 decorator라 불리우며, 부모클래스의 함수를 재정의할때 표시한다.
3. 재정의하게 되면, 자식클래스의 calculate함수를 호출할때, 부모클래스의 함수가 아닌, 재정의된 함수를 호출한다.
4. 데코레이터를 생략해도 동작은한다. 하지만, 타인이 봤을때나 헷갈리지 않도록 표시하는것이 좋다.
본격적으로 main 함수에서 실행해보자.
void main(){
Parent parent = new Parent(3);
Child child = new Child(3);
print(parent.calculate());
print(child.calculate());
}
9
6
첫번째 print는 부모클래스의 calculate함수를 호출하기 때문에 9가 나온것이고,
두번째 print는 자식클래스의 재정의된 calculate함수를 호출하기 때문에 6이 나온것이다.
만약, 자식클래스에서 재정의 하지 않았다면 부모클래스의 calculate를 호출하기 때문에 같은값이 9가 나왔을것이다.
이번에는 자식클래스에서 부모클래스의 함수를 직접 호출한 뒤 연산하는 기능을 넣어보자.
먼저 자식클래스의 calculate함수안에 아래와 같이 소스를 변경한다.
class Child extends Parent {
Child(
int number,
) : super(number = number);
//decorator라 한다.
@override
int calculate(){
int result = super.calculate();
return result + result;
}
}
부모클래스의 calculate를 호출하기 위해선, super라는 키워드를 사용하여 호출할 수 있다는 점을 알수있다.
위 결과값은 result변수에 부모클래스의 calculate값을 호출하여 얻은 9에 한번더 9를 더해서 18이 나온다.
※상속을 받는 자식클래스에서는 부모클래스를 재정의하여 사용할 수 있고,
재정의 한다고 하여 부모클래스의 함수는 영향받지 않는다.
각자의 역할이 다른 클래스는 주축이 되는 클래스로 부터 상속을 받아 주요기능과 값을 사용하며,
기능에 따라 주요기능에 어떠한 값이나 기능을 더해서 사용해야 하는 경우들이 있다.
그럴때 주로 오버라이딩을 사용하면 좋을듯 싶다.
다시말해서, 현재온도를 계산해주는 클래스가 있다고 하자.
첫번째 자식클래스에서는 부모클래스로 부터 얻은 현재 온도에 한글 문장을 붙여서 안내해주는 기능이 있고,
두번째 자식클래스에서는 부모클래스로 부터 얻은 현재 온도에 영어 문장을 붙여서 안내해주는 기능이 있다고 하자.
그럼 자식클래스들에서는 부모클래스로 부터 온도만 받고, 해당 온도를 계산하는 함수를 재정의 한다음
문장을 붙여서 사용할 수도 있는것이다.
적절한 예가 되었을지 모르겠다....
오버라이딩 스터디 끝.