[ upcasting ]
- 서브 클래스 객체를 슈퍼 클래스 타입으로 저장할 수 있다.
- 강제로 캐스팅(형변환)할 필요가 없다. 자동으로 변환된다.
- 장점
- 1) 슈퍼 클래스 타입으로 모든 서브 클래스 객체를 저장할 수 있다.
- 2) 서로 다른 타입의 객체를 하나의 타입으로 관리할 수 있다.
- 단점
- 1) 슈퍼 클래스 타입으로 저장하기 때문에 슈퍼 클래스의 메소드만 호출할 수 있다.
(서브 클래스가 가지고 있는 메소드는 호출이 안 된다는 뜻).
- 2) 이 단점을 해결하기 위해서 메소드 오버라이드(Method Override)를 이용할 수 있다.
[ 메인 메서드 ]
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("홍길동");
s1.setSchool("가산대학교");
s1.eat();
s1.sleep();
s1.study();
System.out.println(s1.getName());
System.out.println(s1.getSchool());
s1.info();
// set을 쓰지 않고 생성자 객체에 바로 저장.
Student s2 = new Student("홍길동", "가산대학교");
s2.eat();
s2.sleep();
s2.study();
System.out.println(s2.getName());
System.out.println(s2.getSchool());
// upcasting (자식 객체를 부모 타입으로 저장시키는 것)
Person p1 = new Student("고길동", "강원대학교");
Person p2 = new Alba("홍길동", "가산대학교", "투썸");
//자식들을 모두 부모인 Person타입으로 관리 가능하다.(여러 객체를 관리하기 편해지는 장점.)
p1.eat();
p1.sleep();
p1.study();
// eat 과 sleep 은 슈퍼 클래스에 있는 메소드여서 호출가능.
// study 는 슈퍼 클래스 메소드가 아니기 때문에 호출 불가능.
// 호출은 Person에서 하지만 실제 실행은 Student에서 실행됨.
p2.eat();
p2.sleep();
p2.study();
p2.working();
// working 도 Person에 빈메소드로 만들어줌(오버라이드)
// 호출은 Person에서 하지만 실제 실행은 Alba에서 실행됨.
}
[ 알바 클래스 ]
public class Alba extends Student {
// Field
private String work;
// Constructor
// new Alba()
public Alba() {
// super(); <-- 없어도 그만, 있어도 그만. Java가 자동 호출.
}
// new Alba("홍길동", "가산대학교", "투썸)
public Alba(String name, String school, String work) {
super(name, school); // Alba 입장에서 슈퍼는 Person이 아닌 Student 이다.
this.work = work;
}
// Getter & Setter
//생성자에서 파라미터 쓰는데 Getter, Setter 쓰는 이유는
//메소드들을 호출 하기 위함이다.
public String getWork() {
return work;
}
public void setWork(String work) {
this.work = work;
}
// Method
@Override
public void working() {
System.out.println("일함");
}
@Override
public void info() {
System.out.println("이름: " + getName());
System.out.println("학교: " + getSchool());
System.out.println("직장: " + work);
// 이름과 학교는 슈퍼클래스에서 가져오니 get으로 가져와줌.
// 직장은 자기가 필드값으로 가지고 있으니 바로 적어줌.
// @Overrid 자동완성 : @Ov + Ctrl + Space
}
[ 학생 클래스 ]
// Student is a Person (is a 상속관계)
// 서브 클래스 is a 슈퍼 클래스(부모)
// super.eat() 같이 메소드들은 다 super로 호출할 수 있다.
public class Student extends Person {
// Field
private String school;
// Constructor
//new Student()
public Student() {
// 반드시 슈퍼 클래스의 생성자 호출이 있어야 하기 때문에,
// 개발자가 슈퍼 클래스의 생성자를 호출하지 않으면 Java가 직접 슈퍼 클래스의 생성자를 호출한다.
// Java가 호출하는 슈퍼 클래스의 생성자는 "디폴트 생성자"만 가능하다.
super(); // 개발자가 작성하지 않아도 자동으로 호출되는 슈퍼 클래스의 디폴트 생성자.
}
// new Student("홍길동", "가산대학교")
public Student(String name, String school) {
// new Student("홍길동") 호출을 위한 코드
super(name); // <- person의 해당 생성자 호출이 됨.
this.school = school;
}
// Method
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public void study() {
System.out.println("공부");
}
// 오버라이드 : 부모가 가진 메소드를 자식이 한 번 더 만들어서 덮어쓰기 하는 것
@Override
public void info() {
System.out.println("이름: " + getName());
System.out.println("학교: " + school);
// 슈퍼클래스에서 가져오니 getName() 적는거고,
// Student 자신이 가지고 있으니 school 필드값만 바로 적어도 된다.
}
[ 사람 클래스 ]
public class Person {
// Field
private String name;
// Constructor
// new Person()
public Person() {
}
// new Person("홍길동")
public Person(String name) {
this.name = name;
}
// Method
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 info() {
System.out.println("이름: " + name);
}
// 실행이 목적이 아닌 호출이 목적인 메소드(오버라이드용)
public void study() {
}
//실행이 목적이 아닌 호출이 목적인 메소드(오버라이드용)
public void working() {
}