어떤 클래스의 특성을 그대로 갖는 새로운 클래스를 정의한 것
상위 클래스 = 부모 클래스 = super class
하위 클래스 = 자식 클래스 = sub class
부모의 생성자와 초기화 블록은 상속 X
자바는 다중 상속 허용X, 단일 상속만 지원. 한 번에 하나만 상속받을 수 있다.
(접근 제한자에 따라 사용 여부 달라진다.)
별도의 extends 선언이 없는 클래스는 extends object가 생략
super를 통해 조상 클래스의 생성자 호출
💡 object가 갖고 있는 속성이 메모리에 맨 처음으로 올라간다person 는 object의 기본 생성자를 호출
가장 마지막에 student 관련된 major, study 등이 메모리에 올라간다.
메모리에는 조상꺼부터 순차적으로 생성됨
같은 설계도 안에서 메소드 명은 동일
애초에 상속 관계가 있을 때만 발생하는 개념
자식 클래스에서 부모 클래스의 특정 메소드를 재정의
에러 발생 예시

@override: annotation. 컴파일러에게 알려주는 주석. 이 메소드는 오버라이드 한 것이다 라고 명시적으로 알려줌
반환형, 매개 변수까지 다 같아야하는데 내가 실수를 했을 때 컴파일러가 내 실수를 잡아줄 수 있도록
가장 최상위 클래스로 모든 클래스의 조상
object의 멤버는 모든 클래스의 멤버

// student 클래스 내부
@Override
public String toString() {
return "Student [major=" + major + ", name=" + name + ", age=" + age + "]";
}
System.out.println(p.toString()); //test05_object.Person@1c4af82c
System.out.println(st.toString()); //Student [major=computer, name=Yang, age=45]
toString()을 재정의한 student 객체만 바뀐 메소드 호출. person 객체는 object 소속 tostring 호출
객체의 주소 비교: == 활용
객체의 내용 비교: euqals 재정의
객체의 해시 코드: 시스템에서 객체를 구별하기 위해 사용되는 정수 값
Hashset, HashMap 등에서 객체의 동일성을 확인하기 위해 사용
equals 메서드를 재정의할 때는 반드시 hashCode도 재정의할 것
미리 작성된 String 이나 Number 등에서 재정의 된 hashCode 활용 권장
해당 선언이 최종 상태, 결코 수정될 수 없음
final 클래스: 상속 금지
final 메소드: overriding 금지
final 변수: 더 이상 값을 바꿀 수 없음. 상수화
상속 관계에 있을 때 조상 클래스의 타입으로 자식 클래스 객체를 참조할 수 있다. (거꾸로는 X)
ex. 메모리에 실제로 올라가 있는 건 student 객체라서 student 속성도, person 속성도 있지만, perosn 속성으로만 바라보겠다.
package test07_polymorphism;
public class Test {
public static void main(String[] args) {
// 다형성
// 조상 클래스의 타입으로 자식 객체를 참조할 수 있다.
Student st = new Student();
Person p = new Student(); // 실제 메모리에 생성된 객체는 student 이지만, person으로 바라보겠다.
Object obj = new Student(); //실제 메모리에 생성된 객체는 student 이지만, object로 바라 보겠다.
// st.
// p.
// obj.
// person에서 tostring을 오버라이드 했음
Object o2 = new Object();
Object o3 = new Person(); // 다형성
// object로 바라본다 하더라도! 실제 객체는 사람이다.
// 메서드를 실행하면 사람의 행동을 한다.
System.out.println(o2.toString());
System.out.println(o3.toString());
}
}
위 → 아래 순으로 생성.
자손 타입 → 조상 타입 ( 묵시적 형 변환 )
형 변환 생략 가능
Student st = new Student();
Person p = st;
Person p = new Person();
Student st =(Student) p;
실제 객체는 사람인데 우리가 학생이라고 생각을 해버림
참조는 할 수 있으나, 실제 메모리에 들어있지 않으면 에러가 난다.
Movie의 자식 SeriesMovie 클래스가 존재할 때,
manager 코드에서 시리즈영화가 아닌 일반 영화만 호출하고자 한다.
// 일반 영화들만 !! 반환
public Movie[] getMovies() {
int cnt=0;
for(int i=0; i<this.size; i++) {
if(!(movieList[i] instanceof SeriesMovie)) {
cnt++;
}
}
Movie[] mList = new Movie[cnt];
int idx=0;
for(int i=0; i<this.size; i++) {
if(!(movieList[i] instanceof SeriesMovie)) {
mList[idx++] = (Movie) movieList[i];
}
}
return mList;
}
(추가예정)
package test09_binding_test;
class Parent {
String x = "parent x";
public void method() {
System.out.println("parent method.");
}
}
class Child extends Parent{
String x = "child x";
@Override
public void method() {
System.out.println("child method.");
}
}
public class BindingTest {
public static void main(String[] args) {
Parent a = new Parent();
Child b = new Child();
System.out.println(a.x);
a.method();
System.out.println(b.x); // hiding
b.method(); // overriding
// 다형성
Parent c = new Child();
// 실제 객체는 child 이므로 행위는 child의 행위를 하게 됨
// 부모 클래스의 타입으로 참조한다 하더라도 = 부모 클래스로 바라본다 하더라도
// 실제로는 child
c.method(); //child method. // 자식의 행위를 하고 있는데...
System.out.println(c.x); //parent x // 부모의 멤버 변수가 튀어나옴 ?
// 동적 바인딩
// 실제 객체의 행위가 나온다! => 다형성
// 멤버 메서드는 => 부모의 관점으로 바라보더라도 자식에서 재정의한 행위가 발생한다.
// 멤버 변수는 다형성을 따르지 않는다. => 부모의 관점으로 바라보면
// 부모의 것을 참조...
}
}
상속받은 필드 포함해서 toString 작성 어케하는지
@Override
public String toString() {
return "SeriesMovie"+ super.toString()+", seriesNum=" + seriesNum + ", episode=" + episode + "]";
}
일반 movie만 조회하는건지, 만약 그렇다면 instanceof가 아닌 다른 메서드를 활용해야하는건지
// 일반 영화들만 !! 반환
public Movie[] getMovies() {
int cnt=0;
for(int i=0; i<this.size; i++) {
if(!(movieList[i] instanceof SeriesMovie)) {
cnt++;
}
}
Movie[] mList = new Movie[cnt];
int idx=0;
for(int i=0; i<this.size; i++) {
if(!(movieList[i] instanceof SeriesMovie)) {
mList[idx++] = (Movie) movieList[i];
}
}
return mList;
}
// 시리즈 영화들을 반환
public SeriesMovie[] getSeriesMovies() {
int cnt=0;
for(int i=0; i<this.size; i++) {
if(movieList[i] instanceof SeriesMovie) {
cnt++;
}
}
SeriesMovie[] sList = new SeriesMovie[cnt];
int idx=0;
for(int i=0; i<this.size; i++) {
if(movieList[i] instanceof SeriesMovie) {
sList[idx++] = (SeriesMovie) movieList[i];
}
}
return sList;
}
부모 클래스에서 private으로 설정한 멤버 변수의 경우, 자식 클래스에서 사용할 수 없다. 메모리에는 올라가있지만, 자식 클래스에서는 사용할 수 없다.