class C {
public void call() {
this.todo();
}
public void todo() {
System.out.println("C");
}
}
class D extends C {
@Override
public void todo() {
System.out.println("D");
}
}
class Ex5 {
public static void main(String[] args) {
D d = new D();
d.call();
}
}
예문에서 부모클래스 C(의 call()메서드)에 존재하는 this는 생성된 객체 d를 가리킨다.
따라서 this.todo()는 D 객체의 메서드 todo()를 가리키게 된다.
C c = new C();
생성된 객체가 부모클래스 C의 c일 경우, this는 객체 c를 가리켰을 것이다.
: 자식 클래스가 부모 클래스의 메서드를 필요에 맞추어 재정의하는 것
= 다 내버려두고 내용만 바꾸는데, 접근은 같거나 더 공개적이고, 상속 관계에서만 가능.
Override vs. Overload
- overloading : (같은 이름이되) 물리적으로 완전히 다른 메서드를 만드는 것 - 중복정의
- overriding : 물리적으로 완전히 같은 메서드를 만드는 것 (덮어씌우기) - 재정의
'물리적으로' 다른 메서드 정의 vs '물리적으로' 같은 메서드 정의
한 클래스 내부 vs 상속을 전제
class Mother {
public void eat() {
// 엄마는 오른손잡이라 '오른손으로 밥 먹는다'
System.out.println("오른손으로 밥 먹는다.");
}
}
// 딸이 왼손잡이라면?
class Daughter extends Mother {
public void eat() {
// '왼손으로 밥 먹는다'로 overriding
System.out.println("왼손으로 밥 먹는다.");
}
}
class Ex1 {
public static void main(String[] args) {
Daughter d = new Daughter();
d.eat();
}
}
class Some {
public String toString() {
return "I'm a Some.";
}
}
class Ex2 {
public static void main(String[] args) {
Some s = new Some();
String str = s.toString();
System.out.println(str);
}
}
// Some에서 toString이 재정의되지 않으면 (override하지 않으면) Object에서 정의된 대로 주소값 반환
// Some에서 재정의되었으므로 실제론 'I'm a Some.'이 출력
오버라이드하기 전 입력하여 메서드가 오버라이딩됨을 알려주는 표시 (annotation의 하나)
1. 컴파일 과정에서 에러 메시지를 출력해주어 쉽게 확인 가능 = 오류 확인 빠름
2. 오버라이딩 전에 표시해주므로 오버라이딩 사용 여부 한 눈에 확인 가능 = 코드 가독성 높아짐
annotation : 코드 안에서 주석처럼 쓰이나, 일반 주석과 달리 코드 진행에 영향을 줄 수 있다.
상속 실수를 막기 위해 JDK1.5부터 생긴 기능.
class A {
public void todo(int n, String str) {
System.out.println("A");
}
}
아래처럼 이름을 실수하거나
class B extends A {
public void tood(int n, String str) {
System.out.println("B");
}
}
패러미터를 실수하더라도
class B extends A {
public void todo(String str, int n) {
System.out.println("B");
}
}
새로운 메서드로 처리되거나, 오버로딩으로 처리되기 때문에,
컴파일 과정에서 에러 메시지가 뜨지 않는다!
class A {
public void todo(int n, String str) {
System.out.println("A");
}
}
class B extends A {
@Override
public void tood(String str, int n) {
System.out.println("B");
}
}
class B가 부모클래스 A의 메서드를 제대로 오버라이딩하지 못했을 때
아래와 같은 에러 메시지를 출력한다.
또한 @Override (annotation 기능) 은 이 메서드가 override되었다는 표식이 되기도 한다.
그러므로 코드 가독성이 높아진다.
class Shape {
public void draw() {
System.out.println("Shape");
}
}
class Circle extends Shape {
@Override
public void draw() {
System.out.println("Circle을 그립니다.");
}
}
class Rectangle extends Shape {
@Override
public void draw() {
System.out.println("Rectangle을 그립니다.");
}
}
class Triangle extends Shape {
@Override
public void draw() {
System.out.println("Triangle을 그립니다.");
}
}
class ShapeTest {
public static void main(String[] args) {
Rectangle s = new Rectangle();
s.draw();
Circle c = new Circle();
c.draw();
Triangle t = new Triangle();
t.draw();
Shape sh = new Shape();
sh.draw();
}
}
this와 같은 쓰임새이나 자기 자신이 아니라 부모 객체를 부른다.
class Human {
private String name;
private int age;
public Human(String name, int age) {
setName(name);
setAge(age);
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return name + "(" + age + ")";
}
}
class Student extends Human {
private int grade;
public Student(String name, int age, int grade) {
super(name, age);
setGrade(grade);
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public String toString() {
// 부모의 toString 호출
return super.toString() + grade + "학년";
}
}
class Ex4 {
public static void main(String[] args) {
Student s = new Student("A", 13, 6);
System.out.println(s);
}
}
- 멤버변수는 재정의 기능이 없다 - (대입으로) 값 바꿀 수 잇으니까
- 메서드는 재정의가 가능하다 (override) - 메서드를 바꿀 수 없으니까
super.num // 바로 위 객체 (부모객체) 접근 가능
super.super.num; // 위의 위 객체는 바로 접근 불가
위로 가려면 부모 객체 안에서 super를 한 번 더 사용하여 나아가는 수 밖에 없다.
class A {
public void grandma() {
System.out.println("Hello, This is grandma!");
}
}
class B extends A {
public void callMom() {
System.out.println("Hello, mommy. This is mother.");
super.grandma();
}
}
class C extends B {
@Override
public void callMom() {
System.out.println("Hello, mommy. This is daughter.");
super.callMom();
}
}
다형성 - 함수형 언어에서 사용. 자바는 함수형 언어가 아니므로(함수형같은 형태를 사용하는 경우는 있더라도) 오버라이드가 다형성과 관련된 것은 아니다.