슈퍼클래스와 서브클래스
Employee 클래스의 몇 가지 기능을 보유하면서 관리자가 직원과 어떻게 다른지 명시하는 클래스 작성
public class Manager extends Employee{
추가된 필드
추가된 메서드 또는 오버라이딩 메서드
}
* 슈퍼클래스는 부모 클래스고 서브클래스는 부모클래스의 기능을 상속받는 자식클래스다.
* 단, 슈퍼클래스라고 더 우월하지 않다는 점이다. 오히려 서브클래스가 슈퍼클래스보다 많은 기능이 있다.
메서드 오버라이딩
public class Manager extends Employee{
...
public double getSalary(){ // 슈퍼클래스의 메서드를 오버라이드한다.
return super.getSalary() + bonus;
}
}
* super는 this와 달리 객체에 대한 참조가 아니다. super는 동적 메서드 조회를 우회하는 지시자이며 특정 메서드를 호출한다.
* 오버라이드를 할떄는 파라미터 타입이 정확하게 일치해야한다.
서브클래스 생성에서 슈퍼클래스의 private인스턴스 변수에 접근할 수 없다. 따라서 슈퍼클래스의 생성자로 해당 인스턴스 변수를 초기화해야한다.
public Manager(String name, double salary){
super(name,salary);
bouns = 0;
}
슈퍼클래스 할당
서브클래스의 객체를 슈퍼클래스의 타입 변수에 할당할 수 있다.
Manager boss = new Manager();
Employee empl = boss; //슈퍼클래스 변수에 할당해도 된다.
double salary = empl.getSalary();
empl의 타입이 Employee 인데도 Manager.getSalary 메서드가 호출된다. *****중요*****
Manager(슈퍼클래스)객체를 Employee에 변수에 할당하는 이유는 뭘까? 이렇게 하면 직원이든 관리자든 문지기든 상관없이 모든 직원에 동작하는 코드를 작성할 수 있기 때문이다. *****
Employee[] staff = new Employee[...];
staff[0] = new Employee(..);
staff[1] = new Manager(..);
staff[2] = new Janitor(..);
슈퍼클래스의 메서드만 호출할 수 있는 단점
Employee empl = new Manager(..);
empl.setBonus(10000); // 컴파일 시간 오류
위와 같이 setBonus메서드(서브클래스의 메서드)를 호출하려고하면 에러가 생긴다.
인터페이스와 마찬가지로 instanceof 연산자로 검사 후 타입변환 연산자를 이용해서 서브클래스 참조로 변환하고 이용하면 된다.
if(empl instanceof Manager){
Manager mgr = (Manager) empl;
mgr.setBonus(10000);
}
final 메서드와 final 클래스
메서드를 final로 선언하면 어느 서브클래스도 해당 메서드를 오버라이드 할 수 없다.
예로 Object의 getClass를 final로 선언하지 않게해서 오버라이드 할 수 있게 했다면 자신이 속한 클래스를 속이는 상황이 생길 수 있다.
자신이 만든 클래스의 서브클래스를 만들지 못하게 하고 싶을 때, final 클래스로 정의할 수 있다.
예로 String, LocalTime, URL같은 final 클래스가 있다.
추상클래스와 추상메서드
클래스는 구현이 없는 메서드를 정의해서 서브클래스가 해당 메서드를 구현하도록 강제할 수 있다.
이렇게 구현이 없는 메서드를 추상메서드라고하고 추상메서드가 포함된 클래스를 추상클래스라고 한다.
* 추상클래스는 인터페이스와 달리 인스턴스 변수와 생성자를 가질 수 있다. **
* 추상클래스는 인스턴스를 생성할 수 없다.
추상클래스와 인터페이스 충돌
public interface Named{
default String getName(){return "";}
}
public class Person{
...
public String getName(){return name;}
}
public class Student extends Person implements Named{.....}
이 상황에서는 항상 인터페이스 구현보다 슈퍼클래스 구현이 우선한다. 그러므로 충돌문제를 해결할 필요가 없다.
클래스우선 규칙은 자바7고의 호환성을 보장한다.