메서드 오버라이딩(Method Overriding) = 메서드 재정의
- 슈퍼클래스로부터 상속받은 메서드를 서브클래스에서 재정의 하는 것
- 기본 슈퍼클래스의 메서드와 동일하게 생긴 메서드를 정의하게 되므로 서브클래스에서는 더 이상 슈퍼클래스의 메서드가 보이지 않음 => 슈퍼클래스의 메서드를 덮어쓰기 때문에 자신의 메서드만 보이게 됨 (= 슈퍼클래스의 메서드는 은닉됨)
- 슈퍼클래스의 메서드에 새로운 기능을 추가하는 경우 기존에 상속된 메서드 내용을 변경하는 경우
오버라이딩 규칙
- 상속 관계 필수!
- 메서드 시그니처(메서드명, 파라미터)가 일치해야함 => 단, 리턴타입은 부모와 같거나 서브클래스 타입으로 변경 가능
- 접근제한자는 같거나 넓은 범위로만 변경 가능(= 좁아질 수 없다!) (넓은) public > protected > default > private (좁음)
오버라이딩 단축키
alt shift s -> v
=> 단, 이미 수동으로 오버라이딩 된 메서드는 표시되지 않는다.
Animal ani = new Animal();
ani.cry();
Dog dog = new Dog();
dog.cry();
Cat cat = new Cat();
cat.cry();
} // main() 메서드 끝
} // Ex2 클래스 끝
// 동물(Animal) 클래스 정의
class Animal {
String name;
int age;
public void cry() {
System.out.println("동물 울음소리!");
}
}
class Dog extends Animal {
// alt shift s -> v
@Override
public void cry() {
System.out.println("멍멍!");
}
}
class Cat extends Animal {
// alt shift s -> v
@Override
public void cry() {
System.out.println("야옹!");
}
}
} // Ex2 클래스 끝
class Parent {
public void parentPrn1() {
System.out.println("슈퍼클래스의 parentPrn1()");
}
public Object parentPrn2() {
System.out.println("슈퍼클래스의 parentPrn2()");
return null;
}
public String parentPrn3() {
System.out.println("슈퍼클래스의 parentPrn3()");
return null;
}
}
class Child extends Parent {
public void childPrn() {
System.out.println("서브클래스의 childPrn()");
}
// 슈퍼클래스 parent로부터 상속받은 parentPen1() 메서드 오버라이딩
// => 슈퍼클래스의 메서드명과 리턴타입, 파라미터가 동일한 메서드 재정의
// => 슈퍼클래스가 가진 parentPrn1() 메서드는 child 인스턴스에서 보이지 않음!
**public void parentPrn1() {
System.out.println("서브클래스에서 오버라이딩 된 parentPrn1()");
}**
}
// Child 클래스의 인스턴스(c)를 생성
Child c = new Child();
c.childPrn(); // 서브클래스에서 정의한 메서드
c.parentPrn1(); // 슈퍼클래스로부터 상속받은 메서드
c.parentPrn2(); // 슈퍼클래스로부터 상속받은 메서드
c.parentPrn3(); // 슈퍼클래스로부터 상속받은 메서드
⇒ 오버라이딩
부모보다 자식클래스의 오버라이딩된 메서드를 먼저 찾음(우선순위가 더 높음)
오버라이딩 시 슈퍼클래스의 접근제한자보다 좁아질 수 없다!
=> 부모가 public일 경우 자식은 무조건 public만 지정 가능!
// private void parentPrn1() { // 컴파일 에러 발생!
// System.out.println("서브클래스에서 오버라이딩 된 parentPrn1()");
// }
// => Cannot reduce the visibility of the inherited method from Parent
// public으로 되어있는 메서드를 상속받았으면, public만 가능하다는 뜻
오버라이딩 시 슈퍼클래스의 리턴타입보다 서브클래스 타입을 명시할 수 있다.
public String parentPrn2() { // Object -> String 변경 가능
// => 부모클래스 타입(Object)으로 리턴타입을 지정했을 시 이 리턴값을 받는 자식클래스(String)로 오버라이딩 가능
System.out.println("서브클래스에서 오버라이딩 된 parentPrn2()");
return null;
}
오버라이딩 시 리턴타입은 기존 리턴타입의 슈퍼클래스 타입이 올 수 없다.
// public Object parentPrn3() { // 컴파일 에러 발생!
// System.out.println("서브클래스에서 오버라이딩 된 parentPrn3()");
// return null;
// }
// => The return type is incompatible with Parent.parentPrn3()
// 오버라이딩 단축키 : alt shift s -> v
@Override // 부모클래스로받은 메서드를 다시 재정의할것이다.
public String parentPrn3() {
System.out.println("서브클래스에서 오버라이딩 된 parentPrn3()");
return null;
}
Car 클래스 상속받는 전기자동차(ElectricCar) 정의
- 멤버변수 : batteryCapacity(배터리 용량, int)
- Car 클래스의 메서드 오버라이딩
- speedUp() : "ElectricCar 전기모터의 힘으로 속력 증가!" 출력(리턴타입, 파라미터 없음)
- speedDown() : "ElectricCar 속력 감소하면서 전기배터리 충전!" 출력(리턴타입, 파라미터 없음)
- addFuel() : "전기차 충전소에서 배터리 충전!" 출력(리턴타입, 파라미터 없음)
class Car {
int speed;
int maxSpeed;
public void speedUp() {
System.out.println("자동차 속력 증가!");
}
public void speedDown() {
System.out.println("자동차 속력 감소!");
}
public void addFuel() {
System.out.println("자동차 연료 주입!");
}
}
Car 클래스 상속받는 디젤자동차(DieselCar) 정의
- 멤버변수 : cc(엔진 배기량, int)
- Car 클래스의 메서드 오버라이딩
- speedUp() : "디젤 엔진의 힘으로 속력 증가!" 출력(리턴타입, 파라미터 없음)
- speedDown() : "디젤 자동차 속력 감소!" 출력(리턴타입, 파라미터 없음)
- addFuel() : "주유소에서 디젤 연료 주입!" 출력(리턴타입, 파라미터 없음)
class ElectricCar extends Car {
int batteryCapacity;
@Override
public void speedUp() {
System.out.println("ElectricCar 전기모터의 힘으로 속력 증가!");
}
@Override
public void speedDown() {
System.out.println("ElectricCar 속력 감소하면서 전기배터리 충전!");
}
@Override
public void addFuel() {
System.out.println("전기차 충전소에서 배터리 충전!");
}
}
Car 클래스 정의
- 멤버변수 : speed(현재속력, int), maxSpeed(최대속력, int)
- 메서드
- speedUp() : "자동차 속력 증가!" 출력(리턴타입, 파라미터 없음)
- speedDown() : "자동차 속력 감소!" 출력(리턴타입, 파라미터 없음)
- addFuel() : "자동차 연료 주입!" 출력(리턴타입, 파라미터 없음)
class DiselCar extends Car {
int cc;
@Override
public void speedUp() {
System.out.println("디젤 엔진의 힘으로 속력 증가!");
}
@Override
public void speedDown() {
System.out.println("디젤 자동차 속력 감소!");
}
@Override
public void addFuel() {
System.out.println("주유소에서 디젤 연료 주입!");
}
}
// 전기자동차 인스턴스 생성
ElectricCar ecar = new ElectricCar();
// speed : 0, maxSpeed :240, batteryCapacity = 5
ecar.speed = 0;
ecar.maxSpeed = 240;
ecar.batteryCapacity = 5;
// ElectricCar 클래스에서 오버라이딩 한 메서드 호출
ecar.speedUp();
ecar.speedDown();
ecar.addFuel();
System.out.println("--------------------------------");
// 디젤자동차 인스턴스 생성
DiselCar dcar = new DiselCar();
// speed : 0, maxSpeed :260, cc= 3000
dcar.speed = 0;
dcar.maxSpeed = 260;
dcar.cc = 3000;
// DieselCar 클래스에서 오버라이딩 한 메서드 호출
dcar.speedUp();
dcar.speedDown();
dcar.addFuel();
}
}
'JAVA' 카테고리의 다른 글
[JAVA] 상속에서의 상속자 (0) | 2023.09.19 |
---|---|
[JAVA] 레퍼런스 super와 접근제한자 (0) | 2023.09.19 |
[JAVA] 상속에서의 생성자 (0) | 2023.09.18 |
[JAVA] has-a 관계(포함) vs is-a 관계(상속) (0) | 2023.09.18 |
[JAVA] 상속(inheritance) (0) | 2023.09.18 |