서브 클래스 객체를 슈퍼 클래스 타입으로 변환하여 저장할 수 있다.
강제로 캐스팅(형변환)할 필요가 없다. 자동으로 promotion 방식으로 변환된다.
메소드 오버라이드
(method override)를 이용할 수 있다. (or downcasting)
((서브클래스)객체).메소드
캐스팅을 잘못할 수 있기 때문에 instanceof
를 이용해서 확인하면 좋다.
사실상 다운캐스팅은 오브젝트 클래스를 사용할 때 쓴다.
public class MainWrapper {
public static void main(String[] args) {
// upcasting 활용 방법
Person p1 = new Student("고길동", "강원대학교"); // subclass 객체를 superclass타입으로 저장 == upcasting
Person p2 = new Alba("홍길동", "가산대학교", "투썸"); // 서로 다른 타입의 Student 와 Alba라는 객체를 Person이라는 하나의 타입으로 관리할 수 있게된다.
// *** 자식 객체를 부모의 타입으로 저장할 수 있다.***
// Student에만 있던 study 메소드를 Person에 추가하여 오버라이드 함.
p1.eat();
p1.sleep();
p1.study();
// Alba에만 있던 working 메소드를 Person에 추가하여 오버라이드 함.
p2.eat();
p2.sleep();
p2.study();
p2.working();
}
}
public class Person {
private String name;
// new Person()
public Person() {
}
// new Person("홍길동")
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat() {
System.out.println("냠냠");
}
public void sleep() {
System.out.println("쿨쿨");
}
// 실행이 목적이 아닌 호출이 목적인 메소드
public void study() {
// student에 있는 study를 호출하기 위해 추가한 메소드
}
public void working() {
// Alba에 있는 working을 호출하기 위해 추가한 메소드
}
// information
public void info() {
System.out.println("이름: " + name);
}
}
// Student is a Person
// 서브 클래스(자식) is a 슈퍼 클래스(부모)
public class Student extends Person{
private String school;
// new Student()
public Student() {
// 반드시 슈퍼 클래스의 생성자 호출이 있어야 하기 때문에,
// 개발자가 슈퍼 클래스의 생성자를 호출하지 않으면 Java가 직접 슈퍼 클래스의 생성자를 호출한다.
// Java가 호출하는 슈퍼 클래스의 생성자는 "디폴트 생성자"만 가능하다.
// 디폴트 생성자만 Java가 호출 할 수 있다.
super(); // 개발자가 작성하지 않아도 자동으로 호출되는 슈퍼 클래스의 디폴트 생성자 호출 형식
}
// new Student("홍길동", "가산대학교")
public Student(String name, String school) {
// new Person("홍길동") 호출을 위한 코드
super(name);
this.school = school;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
// Person에 study메소드를 추가하여 오버라이드 됨. (실제 실행 메소드)
@Override
public void study() {
System.out.println("공부");
}
// information (오버라이드) / annotation 붙이기
@Override
public void info() {
System.out.println("이름: " + getName()); // Person의 getName 호출로 name 보기
System.out.println("학교: " + school);
}
}
상속관계의 클래스 호출의 규칙 : 서브 클래스의 객체를 만드려면 반드시 슈퍼클래스의 생성자를 먼저 호출해야한다.
super : 슈퍼클래스를 표기하는 방법
호출예시 : super();
⇒ 생성자 호출 / super.eat();
⇒ 멤버 호출
// 학교 다니는 알바생
public class Alba extends Student{
private String work; // 일 하는 곳
// new Alba()
public Alba() {
super(); // new Student() 호출과 동일하다. 디폴트 생성자이므로 생략할 수 있다.
}
// new Alba("홍길동", "가산대학교", "투썸")
public Alba(String name, String school, String work) {
super(name, school); // new Student("홍길동", "가산대학교") 호출과 동일하다.
this.work = work;
}
public String getWork() {
return work;
}
public void setWork(String work) {
this.work = work;
}
// Person에 working 메소드를 추가해줘서 오버라이드 됨. (실제 실행 메소드)
@Override
public void working() {
System.out.println("일함");
}
// information (오버라이드) / annotation 붙이기
@Override
public void info() {
System.out.println("이름: " + getName()); // Person 클래스에서 호출
System.out.println("학교: " + getSchool()); // Student 클래스에서 호출
System.out.println("직장: " + work);
}
}
Person p = new Student(); p.eat(); p.sleep(); ((Student)p).study(); // 슈퍼 클래스 타입 -> 서브 클래스 타입으로 변경(다운캐스팅) ((Worker)p).work(); // 잘못된 캐스팅
Person p1 = new Student(); if(p1 instanceof Student) { // instanceof를 이용해서 downcasting 코드 자동 완성이 됨. ((Student) p1).study(); } Person p2 = new Worker(); if(p2 instanceof Worker) { ((Worker) p2).work(); }