부모 클래스에 만들어진 필드, 메소드를 자식클래스가 물려받음. 동일 특성을 재정의할 필요 없어 자식 클래스 간결해짐.
public class Person{
}
public class Student extends Person { //Person을 상속받는 클래스 Student
}
public class StudentWorker extends Student{ //Student를 상속받는 StudentWorker
}
★ extends
키워드 사용 ★
java.lang.Object
클래스public
: 모든 클래스 접근 허용디폴트
: 패키지 내 모든 클래스에 접근 허용protect
: 같은 패키지 내 모든 클래스 접근 허용, 다른 패키지에 있어도 서브 클래스는 슈퍼 클래스의 protected 멤버 접근 가능private
: 다른 모든 클래스에 접근 불허, 클래스 내 멤버들에게만 허용Q. 서브 클래스 객체가 생성될 때, 서브와 슈퍼 클래스의 생성자가 모두 실행되는가?
A. Yes. 둘 다 실행됨. 서브 클래스 객체 생성 시 이 객체에 서브 클래스 멤버와 슈퍼 클래스 멤버가 모두 들어있다.
Q. 서브 클래스의 생성자와 슈퍼 클래스의 생성자 중 누가 먼저 실행되는가?
A. 슈퍼 클래스 -> 서브 클래스 순서로 실행된다.
호출 순서 : 서브 클래스의 생성자가 먼저 호출 -> 서브 클래스의 생성자가 실행 전 슈퍼 클래스 생성자 호출 -> 슈퍼 클래스 생성자 실행 -> 서브 클래스 생성자 실행
super()
이용: 서브 클래스 객체를 슈퍼 클래스 타입으로 타입 변환
class Person { … }
class Student extends Person { … }
Student s = new Student();
Person p = s; // 업캐스팅, 자동타입변환
설명))
그냥 슈퍼클래스를 쓴다는 게 아니라
Person p;
Student s = new Student("이재문");
p=s; //업캐스팅
이게 레퍼런스 p가 Student 객체의 멤버 중에서 그 슈퍼클래스인 Person의 멤버만 접근한다는 의미!!
"Student 객체 멤버 중 슈퍼클래스 멤버만 접근"이란 의미가 중요
: 슈퍼 클래스 객체를 서브 클래스 타입으로 변환. 개발자의 명시적 타입 변환 필요.
class Person {...}
class Student extends Person {...}
...
Person p = new Student("이재문"); //업캐스팅
...
Student s = (Student)p; //다운캐스팅, (Student)의 타입 변환 표시 필요
업캐스팅된 레퍼런스로 객체의 타입을 판단하기가 어려움 -> 슈퍼 클래스는 여러 서브 클래스에 상속되기 때문
instanceof 연산자
레퍼런스가 가리키는 객체의 타입 식별을 위해 사용
객체레퍼런스 instanceof 클래스타입
연산 결과 : true/false의 불린 값
슈퍼 클래스의 메소드를 서브 클래스에서 재정의 (슈퍼 클래스의 메소드 이름, 매개변수 타입과 개수, 리턴 타입 등 모든 것을 동일하게 작성)
<동적 바인딩 발생!>
서브 클래스에 오버라이딩된 메소드가 무조건 실행되는 동적바인딩 (슈퍼 클래스 메소드가 무시, 덮어쓰기로 번역되기도 함)
오버라이딩 : 슈퍼 클래스에 선언된 메소드를 각 서브 클래스들이 자신만의 내용으로 새로 구현
super
: 슈퍼 클래스의 멤버를 접근할 때 사용되는 레퍼런스
정적 바인딩
으로 처리: 선언되어 있으나 구현되지 않은 메소드, abstract
로 선언됨
public abstract String getName();
pubilc abstract void setName(String s);
추상 메소드는 서브 클래스에서 오버라이딩하여 구현해야함
//1. 추상 메소드 하나 이상 가진 클래스
abstract class Shape { // 추상 클래스 선언
public Shape() { }
public void paint() { draw(); }
abstract public void draw(); // 추상 메소드
}
//2. 추상 메소드가 없는 클래스
abstract class MyComponent { // 추상 클래스 선언
String name;
public void load(String name) {
this.name = name;
}
}
★ 추상 클래스는 객체를 생성할 수 없다!★
추상 클래스 상속의 2가지 경우
추상 클래스의 단순 상속 - 서브 클래스도 추상 클래스
-> 추상 클래스 상속받고 추상 메소드는 구현하지 않은 경우, 서브 클래스도 abstract로 선언해야함
추상 클래스 구현 상속 - 서브 클래스는 추상 클래스 X
-> 서브 클래스에서 슈퍼 클래스의 추상 메소드 구현 (오버라이딩), 서브 클래스는 추상 클래스가 아님
클래스가 구현해야 할 메소드들이 선언되는 추상형
interface
키워드로 선언함
public interface SerialDriver {...}
인터페이스의 추상 메소드를 모두 구현한 클래스 작성
implements
키워드 사용class SamsungPhone implements PhoneInterface { // 인터페이스 구현
// PhoneInterface의 모든 메소드 구현
public void sendCall() { System.out.println("띠리리리링"); }
public void receiveCall() { System.out.println("전화가 왔습니다."); }
// 메소드 추가 작성
public void flash() { System.out.println("전화기에 불이 켜졌습니다."); }
}
=> 인터페이스는 스펙을 주어 클래스들이 그 기능을 서로 다르게 구현할 수 있도록 하는 클래스의 규격 선언이며, 클래스의 다형성을 실현하는 도구이다.