다형성의 장점
다형성의 조건
// 부모 클래스
public class Camera {
public String name;
public Camera() {
this("카메라");
}
protected Camera(String name) {
this.name = 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 + "의 주요 기능 : 사진 촬영, 동영상 녹화");
}
}
// 상속을 못하게 final
public final class ActionCam extends Camera {
// 렌즈를 바꾸지 못하게 하는 방법
// public final String lens = "광각렌즈";
public final String lens;
// final를 추가해서 직접 값을 처리하는 경우도 있고 생성자를 총해서 처리하는 방법도 있다
public ActionCam() {
super("액션 카메라");
lens = "광각렌즈";
}
public final void makeVideo() {
System.out.println(this.name + " : " + this.lens + " 비디오 제작합니다");
}
}
// Carmera의 자식 클래스
public class FactoryCam extends Camera {
public FactoryCam() {
super("공장 카메라");
}
public void detecFire() {
// 화재 감지
System.out.println("화재 감지합니다");
}
// 메소드 오버라이딩
public void showMainFeature() {
System.out.println(this.name + "의 주요 기능 : 화재 감지");
}
public void recordVideo() {
// 동영상 촬영
super.recordVideo();
detecFire();
}
}
public class SpeedCam extends Camera {
public SpeedCam() {
super("과속닥속 카메라");
}
public void checkSpeed() {
// 속도 체크
System.out.println("속도를 측정합니다");
}
public void recognizeLicensePlate() {
// 번호 인식
System.out.println("번호판 인식");
}
// 이 소스코드를 컴퓨터가 알아볼수 있는 형태로 바꾸는 것을 컴파일 그 역할을 하는게 컴파일러
@Override // annotation(주석) 평소 쓰는 주석이랑 다르다
public void showMainFeature() {
System.out.println(this.name + "의 주요 기능 : 속도 측정, 번호 인식");
}
public void takePicture() {
// 사진 촬영
// 중복된 부분을 사용, 상속을 하는 의미가 없어짐
// System.out.println(this.name + " 사진을 촬영합니다.");
super.takePicture();
checkSpeed();
recognizeLicensePlate();
}
}
public class _14_Polymorphism {
public static void main(String[] args) {
// 다형성
// class Person : 사람
// class Student extends Person : 학생 (학생은 사람이다)
// class Teacher extends Person : 선생님 (선생님은 사람이다)
/*Camera camera = new Camera();
FactoryCam factoryCam = new FactoryCam();
SpeedCam speedCam = new SpeedCam();*/
// 다형성 이용: 자식클래스 이름대신 부모클래스 이름으로 형태가 서로 다른 객체를 형성가능
Camera camera = new Camera();
Camera factoryCam = new FactoryCam();
Camera speedCam = new SpeedCam();
camera.showMainFeature();
factoryCam.showMainFeature();
speedCam.showMainFeature();
System.out.println("-------------");
Camera[] cameras = new Camera[3];
cameras[0] = new Camera();
cameras[1] = new FactoryCam();
cameras[2] = new SpeedCam();
for (Camera cam: cameras) {
cam.showMainFeature();
}
System.out.println("-------------");
// 오류 나는 이유는 정의할 떄 Camera클래스(부모)로 했기 때문이다
// 그렇기 때문에 부모클래스에 있는 메소드만 사용가능
// speedCam.checkSpeed();
// factoryCam.detecFire();
}
}
상위 클래스 타입의 참조 변수로 하위 클래스의 객체를 참조하는 다형성의 핵심적인 부분이다.
그러나, 하위 클래스 타입으로 상위 클래스의 객체를 참조하는 것은 허용되지 않는다.
참조 변수의 형 변환
형 변환을 위한 조건
FactoryCam factoryCam = new FactoryCam();
// 업 캐스팅 () 생략 가능
Camera camera = (Camera) factoryCam;
// 다운 캐스팅 () 생략 불가능
FactoryCam factoryCam = (FactoryCam)camera;
instanceof 연산자
// 위 오류를 해결하는 방법 = 형변환을 통해서 메소드에 접근
// instanceof를 사용 : 이 객체가 어떤 클래스의 객체인지 확인
if (camera instanceof Camera) { // camera의 객체가 Camera로 부터 만들어진 객체라면
System.out.println("카메라입니다");
}
if (factoryCam instanceof FactoryCam) { // factoryCam이 FactoryCam의 인스턴스인지
((FactoryCam)factoryCam).detecFire();
}
if (speedCam instanceof SpeedCam) {
((SpeedCam)speedCam).checkSpeed();
((SpeedCam) speedCam).recognizeLicensePlate();
}
// 자바는 기본적으로 Object라는 클래스를 상속
// 어떤 객체든 모든 클래스 객체를 넣을 수 있다
Object[] obj = new Object[3];
obj[0] = new Camera();
obj[1] = new SpeedCam();
obj[2] = new FactoryCam();
국비학원에서 배운것과 따로 공부한 것을 정리한 것입니다
참고
나도코딩 유튜브