Object ob = new Person(); // O
Person per = new Student(); // O
Student stu = new Person(); // X
Object ob = new Student(); // Object의 영역까지만 접근 가능
Person per = new Student(); // Person의 영역까지 접근 가능
Student st = new Student(); // Student의 모든 영역 접근 가능
자손타입
-> 조상타입
(묵시적 형 변환)Student st = new Student();
person p = st;
조상타입
-> 자손타입
(명시적 형 변환)Person p = new Person();
Student st = (Student)p;
Person p2 = new Student();
Student st2 = (Student)p2;
❗
Student()
생성자로 생성해도 컴파일러는 이를 Person으로 인식하기 때문에 형 변환이 필요하다.
🌟
ClassCastException
자손타입으로 형 변환을 거친 참조 변수가 조상타입에는 없는 속성을 가져오려 할때 발생하는 예외
instanceof
연산자Person per = new Student();
if(per instanceof Student) {
System.out.println("학생 맞음");
((Student)per).study();
}
❗
.
이 우선 순위가 높기 때문에 괄호 사용이 필수적이다.
class Parent {
String x = "parent";
public String method() {
return "아빠임";
}
}
class Child extends Parent {
String x = "Child";
@Override
public String method() {
return "아들임";
}
}
public class Test {
public static void main(String[]args) {
Parent p = new Child();
p.x; // parent
p.method(); // 아들임
}
}
동적 바인딩
.abstract
키워드를 메서드 선언부에 추가abstract
를 추가public abstract class Chef {
String name;
int age;
String speciality;
public void eat() {
System.out.println("야무지게 먹어야지");
}
public abstract void cook();
}
🤷♂️ 구현부에 빈 괄호만 남겨놓으면 되는거 아님?
- 강제성이 사라져 재작성의 필요가 사라져버린다. abstract는 자식클래스의 오버라이딩에 강제성을 부여한다. 그리고 부모가 구현하고 싶은 내용이 없다고 해서 구현 자체를 빼버리면 동적바인딩에 의해 자식의 오버라이딩된 함수가 실행되는 기회를 없애게 된다.
Chef chef1 = new Chef(); // X
Chef chef2 = new KFoodChef(); // O
조상 클래스에서 상속 받은 abstract 메서드를 재정의 하지 않은 경우, 클래스 내부에 abstract 메서드가 있으므로 자식 클래스는 abstract 클래스가 되어야 한다.
추상 클래스도 익명 클래스 문법을 이용해서 1회 한정으로 구현하고 인스턴스를 만들 수 있다.
Chef c2 = new Chef() {
@Override
public void cook() {
System.out.println("신이라 뭐든 요리해요.");
}
}
좋은 글 감사합니다. 자주 올게요 :)