이전 시간에 학습한 상속 예제에서 super를 이용해 부모클래스의 메소드와 생성자를 호출하는 방법에 대하여 공부해보자.
상속 시간에 기본 카메라(Camera), 화재감지카메라(FactoryCam), 속도감지카메라(SpeedCam)을 생성하였다.
그리고 각각 Camera 클래스를 부모클래스로, FactoryCam과 SpeedCam 클래스를 자식클래스로 설정하였다.
부모클래스인 Camera에는 takePicture(), recordVideo(), showMainFeature()메소드가 있었다.
public class Camera {
public String name;
public Camera() {
this.name = "카메라";
}
//카메라의 기본 기능 메소드로 정의
public void takePicture(){
//사진촬영
System.out.println(this.name + ": 사진을 촬영합니다.");
}
public void recordVideo(){
//동영상 녹화
System.out.println(this.name + ": 동영상을 녹화합니다.");
}
public void showMainFeature(){
System.out.println(this.name + "의 주요 기능 : 사진 촬영, 동영상 녹화");
}
}
그리고 자식 클래스인 FactoryCam 클래스에는 화재감지기능 detectFire() 메소드가 있고,
또 다른 자식클래스인 SpeedCam 클래스에는 속도감지기능 checkSpeed(), recognizeLicensePlate() 메소드가 있다.
FactoryCam과 SpeedCam은 부모클래스로부터 takePicture(), recordVideo()를 물려받아 사용하고 있다.
이 때 FactoryCam 클래스에서 부모클래스의 recordVideo() 호출 시 detectFire() 메소드를 함께 실행하고 싶다면 어떻게해야할까?
이전 시간에 학습한 메소드오버라이딩을 활용하면 FactoryCam 클래스를 아래와 같이 수정할 수 있다.
package chap_07.camera;
public class FactoryCam extends Camera{ //자식클래스
public FactoryCam() {
this.name = "공장 카메라";
}
public void recordVideo(){
//동영상 녹화
System.out.println(this.name + ": 동영상을 녹화합니다.");
detectFire();
}
public void detectFire(){
//화재 감지 카메라 기능
System.out.println("화재를 감지합니다.");
}
public void showMainFeature(){
System.out.println(this.name + "의 주요 기능 : 화재감지");
}
}
메소드 오버라이딩을 통해 recordVideo() 메소드를 재정의하고 해당 메소드 내에서 detectFire()를 호출하는 방식으로 수정하면 된다.
하지만 이런식으로 오버라이딩을 과사용하게 된다면, 상속의 의미가 없어진다.
왜냐하면 상속의 장점은 부모클래스의 코드만 수정하여도 자식클래스에 모두 적용되어 유지보수/관리가 용이한 점이었는데 위와 같이 오버라이딩한다면 recordVideo()의 코드의 수정이 필요할때, 부모클래스와 자식클래스에서 각각 수정이 진행되어야한다.
이러한 문제를 개선할 수 있는 것이 Super이다.
위의 FactoryCam 클래스를 Super를 적용하여 다시 수정해보자.
package chap_07.camera;
public class FactoryCam extends Camera{ //자식클래스
public FactoryCam() {
this.name = "공장 카메라";
}
public void recordVideo(){
//동영상 녹화
super.recordVideo();
detectFire();
}
public void detectFire(){
//화재 감지 카메라 기능
System.out.println("화재를 감지합니다.");
}
public void showMainFeature(){
System.out.println(this.name + "의 주요 기능 : 화재감지");
}
}
FactoryCam 클래스에서 recordVideo() 메소드를 오버라이딩(재정의)할때 super를 활용하게 되면,
부모 클래스 내의 메소드를 super.recordVideo()로 호출하여 사용하게 된다.
recordVideo() 코드의 수정이 필요할 때 부모클래스에서만 수정하여도 자식클래스에 동일하게 상속되게된다.
동일한 예제로 SpeedCam 클래스도 아래와 같이 super를 사용할 수 있다.
package chap_07.camera;
public class SpeedCam extends Camera { //자식클래스
public SpeedCam() {
this.name="과속단속 카메라";
}
public void takePicture(){
//사진촬영
super.recordVideo();
checkSpeed();
recognizeLicensePlate();
}
public void checkSpeed(){
//속도체크
System.out.println("속도를 측정합니다.");
}
public void recognizeLicensePlate(){
//자동차 번호 인식
System.out.println("차량번호를 인식합니다.");
}
public void showMainFeature(){
System.out.println(this.name + "의 주요 기능 : 속도 측정, 차량번호 인식");
}
}
이번에는 super를 통해 부모클래스의 생성자를 호출하는 방법을 학습해보자.
우선 부모클래스 Camera은 변수 name을 설정하는 생성자를 아래와 같이 가지고 있다.
public String name;
public Camera() {
this.name = "카메라";
}
위 생성자를 아래와 같은 형식으로 변경해보자.
1) 기본 생성자 public Camera() 호출 시 this("카메라") 를 실행하도록 하였다.
this 는 해당 클래스를 지칭하므로 Camera 클래스 내에 전달값 1개를 필요로하는 생성자가 실행된다.
2) 위에서 호출한 전달값 1개, name을 받는 protected Camera(String name)을 새로 생성하였다.
protected Camera(String name) 을 호출하면 전달받은 name 값을 Camera 클래스 내 name 변수에 대입한다.
참고 ) protected : 같은 패키지 내에서는 접근 가능, 다른 패키지인 경우 자식 클래스에서만 접근 가능
기존 코드와 결과적으로 같은 기능을 수행하지만 protected 로 접근제어자를 설정하여 name 변수 값을 설정하도록 코드를 수정하였다.
이번에는 자식클래스인 FactoryCam과 SpeedCam에서 위의 부모클래스 생성자를 호출하여 name 값을 설정하도록 해보자.
자식클래스 내에서 super() 를 선언 시 부모클래스의 생성자를 불러오게된다.
위 예제에서는 super("name") 전달값 name과 함께 부모클래스의 생성자를 호출하여 각 객체별로 name을 설정할 수 있다.
'Spec UP - Backend > 나도코딩의 자바기본편' 카테고리의 다른 글
Chap_07. Final (0) | 2023.05.02 |
---|---|
Chap_07. Reference 참조 (0) | 2023.05.02 |
Chap_07. 다형성 (0) | 2023.04.28 |
Chap_07. 메소드 오버라이딩 (0) | 2023.04.28 |
Chap_07. 상속 (0) | 2023.04.28 |
댓글