코딩 이야기
JAVA 메소드 재정의 본문
메소드 재정의
부모 클래스의 모든 메소드가 자식 클래스에 맞게 되어 있다면 이상적이지만, 어떤 메소드는 자식 클래스가 사용하기에 적합하지 않습니다.이 경우 상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야 하는데 이것을 메소드 재정의라고 합니다.
메소드 재정의 방법
- 부모의 메소드와 동일한 시그니처(리턴 타입, 메소드 이름, 매개 변수 목록)를 가져야 합니다.
- 접근 제한을 더 강하게 재정의할 수 없습니다.
- 새로운 예외(Exception)를 throws할 수 없습니다.
* 접근 제한을 더 강하게 재정의할 수 없다 : 부모 메소드가 public 접근제한을 가지고 있을 경우 재정의하는 자식 메소드는 default나 private접근제한으로 수정할 수 없다는 뜻입니다. 단, 반대의 경우는 가능합니다. default>>public 으로 제한가능
다음 예제는 Calcuator의 자식 클래스인 computer에서 원의 넒이를 구하는 Calculator의 areaCircle()메소드를 사용하지 않고, 좀 더 정확한 원의 넒이를 구하도록 재정의했습니다.
부모클래스
package ch07;
public class Calculator {
double areaCircle(double r) {
System.out.println("Calculator 객체의 areaCicle() 실행");
return 3.14159*r*r;
}
}
자식 클래스
package ch07;
public class Computer extends Calculator {
@Override
double areaCircle(double r) {
System.out.println("Computer 객체의 areaCircle() 실행"); // 재정의
return Math.PI*r*r;
}
}
메소드 재정의 테스트
package ch07;
public class ComputerExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
int r = 10;
Calculator calculator = new Calculator();
System.out.println("원면적 : "+calculator.areaCircle(r));
System.out.println();
Computer computer =new Computer();
System.out.println("원면적 :"+computer.areaCircle(r));
}
}
부모 메소드 호출
자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황이 발생한다면 명시적으로 super 키워드를 붙여서 부모 메소드를 호출할 수 있습니다.
super.부모메소드();
예제)
Airplane 클래스를 상속해서 SupersonicAirplane 클래스를 만들어 보겠습니다. Airplane의 fly() 메소드는 일반 비행이지만 SupersonicAirplane의 fly() 메소드는 초음속 비행 모드와 일반 비행 모드 두 가지로 동작합니다.
super 변수
package ch07;
public class Airplane {
public void land() {
System.out.println("착륙합니다.");
}
public void fly() {
System.out.println("일반비행합니다.");
}
public void takeOff() {
System.out.println("이륙합니다,");
}
}
super 변수
package ch07;
public class SupersonicAirplane extends Airplane {
public static final int NORMAL = 1;
public static final int SUPERSONIC = 2;
public int flyMode = NORMAL;
@Override
public void fly() {
if(flyMode == SUPERSONIC) {
System.out.println("초음속 비행합니다.");
} else {
super.fly();
}
}
}
super 변수
package ch07;
public class SupersonicAriplaneExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
SupersonicAirplane sa = new SupersonicAirplane();
sa.takeOff();
sa.fly();
sa.flyMode = SupersonicAirplane.SUPERSONIC;
sa.fly();
sa.flyMode = SupersonicAirplane.NORMAL;
sa.fly();
sa.land();
}
}
final 클래스와 final 메소드
final 키워드는 클래스,필드,메소드를 선언할 때 사용할 수 있는데, 해당 선언이 최종 상태이고 결코 수정될 수 없음을 뜻합니다. final키워드는 클래스, 필드, 메소드 선언에 사용될 경우 해석이 조금씩 달라지는데 필드를 선언할 때 final이 지정되면 초기값 설정 후 더 이상 값을 변경할 수 없습니다.
상속할 수 없는 final 클래스
클래스를 선언할 때 final 키워드르 class 앞에 붙으면 이 클래스는 최종적인 클래스이므로 상속할 수 없는 클래스가 됩니다. 즉, final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들수 없다는 것입니다.
public final class 클래스 {...}
final 클래스의 대표적인 예는 자바 표준 API에서 제공하는 String 클래스입니다. String 클래스는 다음과 같이 선언되어 있습니다.
public final class String {...}
클래스 선언시 final 키워드를 class 앞에 붙이면 최종적인 클래스가 되어 자식 클래스를 만들 수 없습니다.
상속할 수 없는 final 클래스
package ch07;
public final class Member {
}
재정의할 수 없는 final 메소드
메소드를 선언할 때 final 키워드를 붙이면 이 메소드는 최종적인 메소드이므로 재정의할 수 없는 메소드가 됩니다.
즉, 부모 클래스를 상속해서 자식 클래스를 선언할 때 부모 클래스에 선언된 final 메소드는 자식 클래스에서 재정의할 수 없다는 것입니다.
public final 리턴타입 메소드( [매개변수,...]) {...}
메소드 선언 시 final 키워드를 붙이면 최종적인 메소드가 되어 재정의 할 수 없습니다.
재정의할 수 없는 final 메소드
package ch07;
public class Car {
//필드
public int speed;
//메소드
public void speedUP() {speed += 1;}
//final 메소드
public final void stop() {
System.out.println("차를 멈춤");
speed = 0;
}
}
재정의할 수 없는 final 메소드
package ch07;
public class SportsCar extends Car {
@Override
public void speedUp() {speed += 10;}
@Override
public void stop() {
System.out.println("스포츠카를 멈춤");
speed = 0; // 재정의할 수 없음
}
}
protected 접근제한자
상속과 관련이 있는 protected가 어떤 역활을하는지 알아보자.
protected는 public과 default 접근 제한의 중간쯤에 해당합니다. 같은 패키지에서 default와 같이 접근 제한이 없지만 다른 패키지에서는 자식 클래스만 접근을 허용합니다.
protected는 필드와 생성자, 메소드 선언에 사용될 수 있습니다.
protected 접근 제한자
package ch07;
public class A {
protected String field;
protected A() {}
protected void method() {}
}
protected 접근 제한자
package ch07;
public class B {
public void method() {
A a = new A();
a.field ="value";
a.method();
}
}
protected 접근 제한자 (A클래스 접근 불가능) 다른패키지
package ch07;
public class C {
public void method() {
A a = new A();
a.field ="value";
a.method();
}
}
protected 접근 제한자 (A클래스 접근가능) 자식관계
package ch07;
public class D extends A {
public D() {
super();
this.field ="value";
this.method();
}
}
'JAVA' 카테고리의 다른 글
JAVA 객체타입확인 (0) | 2023.02.15 |
---|---|
JAVA 타입변환과 다형성 (0) | 2023.02.13 |
JAVA 상속 (0) | 2023.02.13 |
JAVA 접근 제한자 (0) | 2023.02.10 |
JAVA 싱글톤 , final 필드와 상수 (0) | 2023.02.10 |