참고)
- 부모 클래스(parent class) = 상위 클래스(super class) = 기초 클래스(base class)
- 자식 클래스(child class) = 하위 클래스(sub class) = 파생 클래스(derived class)
class 자식 클래스 extends 부모클래스 {
}
private 접근 제어자로 된 필드를 제외한 상속된 필드들은 직접적으로 사용이 가능합니다.
superClass에서 선언된 필드와 같은 이름으로 subClass에서 필드로 정의할 수 있습니다. (Hiding it, not recommended)
새로운 필드와 메소드를를 subClass에서 추가할 수 있습니다. 이건 superClass에는 적용이 되지 않습니다.
상속된 메소드는 직접 사용할 수 있고 superClass에서 정의한 메소드를 subClass에서 재정의할 수 있습니다. 이때 동일한 Signature를 가지게됩니다. (Overriding it)
subClass에서 constructor()를 작성할 수 있고 super keyword를 통해 superClass의 constructor()를 불러올 수 있습니다.
superClass의 static method와 동일한 이름을 subClass의 instance method 이름으로 할 수 없습니다.
superClass의 instance method와 동일한 이름을 subClass의 static method 이름으로 할 수 없습니다.
예시)
C -> B -> A
C : B자원과 A자원 모두 공유 가능

ㄴ 기본생성자 정의

ㄴ B가 A를 상속받음
ㄴ 기본생성자 정의

ㄴ C가 B를 상속받음
ㄴ 기본생성자 정의

ㄴ C( ) : C 생성자 호출
ㄴ 기본생성자 정의 시점 : 기본생성자의 구현내용은 이미 객체가 만들어지고 난 뒤의 시점
ㄴ 음? 나는 C 생성자만 출력했는데 왜 A, B 기본생성자의 구현내용도 같이 출력이 됬지?
ㄴ super(); : 기본생성자 처럼 내가 따로 정의 안했을 시 컴파일러가 모든 생성자함수의 첫줄에 항상 추가, 상위 클래스의 기본생성자를 가리킴
ㄴ 코드 해석
C() : C 생성자 호출
-> super( ) : C의 기본생성자 내부에서 super호출 = 상위클래스의 기본 생성자 = B()
↓
B() : B생성자 호출
-> super() : B의 기본생성자 내부에서 super호출 = 상위클래스의 기본 생성자 = A()
↓
A() : A 생성자 호출
=> 그래서 A, B, C 기본생성자의 구현내용이 모두 출력됨

ㄴ 생성자 함수 : 스택영역이다
ㄴ C, B, A = 생성자 함수 : 객체를 만드는 역할
ㄴ스택구조 : 먼저호출된게 마지막에 나온다
ㄴ C호출 B호출 A호출 -> A객체 생성 B객체생성 C객체생성
ㄴ 객체가 만들어 지면 이제 사라진다ㅏ

ㄴ 힙영역
ㄴ A, B, C객체가 소유하고 있는 자원

ㄴ B생성자 함수 호출
ㄴ B에서 A객체의 자원 호출

ㄴ B : A, B 객체의 자원 소유

ㄴ C : A, B, C 객체의 자원 소유
super()만 추가 해 줌참고)
this가 함수의 지역변수 : 현재 클래스에 생성되어있는 객체의 주소값이 담겨있음
ㄴ 왜? 객체의 자원을 접근하기 위해서
예시)
class Parent {
String parentVariable = "부모 클래스 변수";
void parentMethod() {
System.out.println("부모 클래스의 메서드");
}
}
-------------------------------------------------------------------------------
class Child extends Parent {
String childVariable = "자식 클래스 변수";
void childMethod() {
System.out.println("자식 클래스의 메서드");
}
void accessParent() {
// super 키워드를 사용하여 부모 클래스의 변수와 메서드에 접근할 수 있습니다.
System.out.println(super.parentVariable); // 부모 클래스의 변수 출력
super.parentMethod(); // 부모 클래스의 메서드 호출
}
}
-------------------------------------------------------------------------------
public class SuperExample {
public static void main(String[] args) {
Child child = new Child();
child.accessParent(); // 자식 클래스에서 부모 클래스 멤버에 접근하는 메서드 호출
}
}
-------------------------------------↓출력↓-------------------------------------
부모 클래스 변수
부모 클래스의 메서드
참고)
this(...) : 현재 클래스의 생성자 함수를 클래스 내부에서 호출할 때 사용
예시)
class Parent {
Parent() {
System.out.println("부모 클래스의 생성자");
}
}
-------------------------------------------------------------------------------
class Child extends Parent {
Child() {
// 부모 클래스의 생성자 호출
super(); // 이 줄에서 super()를 호출하여 부모 클래스의 생성자를 호출합니다.
System.out.println("자식 클래스의 생성자");
}
}
-------------------------------------------------------------------------------
public class SuperConstructorExample {
public static void main(String[] args) {
Child child = new Child();
}
}
-------------------------------------↓출력↓-------------------------------------
부모 클래스의 생성자
자식 클래스의 생성자
예시) 컴파일러는 기본 super()만 추가해준다
package exam03;
public class Student {
protected int id;
protected String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
}
-------------------------------------------------------------------------------
package exam03;
public class HighSchoolStudent extends Student {
public HighSchoolStudent() {
super(1000, "이이름");
}
}
-------------------------------------------------------------------------------
package exam03;
public class Ex06 {
public static void main(String[] args) {
HighSchoolStudent highSchoolStudent = new HighSchoolStudent();
System.out.println(highSchoolStudent.id);
System.out.println(highSchoolStudent.name);
}
}
-------------------------------------↓출력↓-------------------------------------
1000
이이름


ㄴ super() : 상위클래스의 기본생성자참조
ㄴ 컴파일러는 매개변수가 있든 말든 기본=super()만 추가해 줌
ㄴ 상위 클래스에 있는 기본생성자 함수에는 매개변수가 있는데 하위클래스에는 매개변수 없어서 에러 뜸
ㄴ 문제해결 방법
-> ① 상위 클래스에 기본 생성자를 추가해줌
-> ② 하위클래스 super()에 매개변수를 넣어주기
① 상위 클래스에 기본 생성자를 추가해줌


ㄴ 기본생성자는 생성자함수가 없을 때만 추가해줌
ㄴ 상위클래스에 이미 생성자함수가 한개 있기 때문에 컴파일러가 자동으로 추가 안해줘서 내가 따로 써줘야 함
ㄴ 따로 써줌으로써 오류 해결
② 하위클래스 super()에 매개변수를 넣어주기



상속시에만 가능
인스턴스 메서드에서만 가능
하위클래스에 상위클래스와 동일한 메서드가 있으면 하위클래스 메서드가 우선
부모 클래스의 메서드와 자식 클래스의 메서드의 이름, 매개변수 유형, 반환 유형이 동일해야 함
ㄴ 그렇지 않다면 재정의한 메서드를 기존 메서드와 다른 메서드로 인식함
접근 제어자는 부모 클래스의 메서드보다 더 넓은 범위로 변경가능
ㄴ 단, private은 접근 자체가 안되므로 불가
ex) 부모 클래스의 메서드가 protected로 선언되었다면 자식 클래스에서는 protected 또는 public으로 재정의할 수 있다
자식 클래스에서 재정의된 메서드는 부모 클래스의 메서드보다 더 구체적인 예외를 선언할 수 있다
ex) 부모 클래스의 메서드가 throws IOException을 선언했다면 자식 클래스에서는 throws FileNotFoundException을 선언할 수 있습니다.


ㄴ super.move(); : Animal이라는 객체의 move()라는 메서드를 호출

ㄴ 실수로 함수명 잘못정의한거 알려줌
@Override 단축키
마우스 우클릭
예시)




ㄴ 주소가 각각 매핑되어 있지만 접근한 메소드는 같음
ㄴ 현재 Human에 정의 된 move()가 없기 때문에 상속받은 Animal.move() 접근함


ㄴ Human에 move()가 정의되었기 때문에 Animal.move()가 아닌 Human.move()주소값을 통해 접근함

ㄴ 모두 같은 메서드를 참조한다






ㄴ Animal, Tiger, Human 에 있는 move()는 서로 다른 move()이다
정적메서드는 가상메서드테이블 과정 없이 클래스명으로 바로 접근 가능
인스턴스메서드는 가상메서드테이블 과정을 거쳐 접근 가능
메서드 여러개 필요 없으니 하나의 자원 move()만 접근

ㄴ 주스는 동일하지만 양이 줄어듬

A a = c;
ㄴ A라는 클래스에 c를 담는다
-> C클래스의 자료형이 A클래스의 자료형으로 바뀜(자료형 바뀜)❓



ㄴ 같은 말이다
ㄴ A클래스에 C객체를 담았다
ㄴ C객체를 만들고 내용물을 A에 담았다
예시)

ㄴ 다형성 그림

ㄴ Animal 클래스 정의

ㄴ Bild 클래스 정의

ㄴ Human 클래스 정의

ㄴ Tiger 클래스 정의

ㄴ 객체 생성 -> 호출

ㄴ Human human = new Human(); -> Animal human = new Human();로 바꿔도 ㅇㅋ(다형성)

ㄴ 배열
ㄴ ❓출력값이 이해가 안되넹
ㄴ 자료형은 Animal(상위클래스)이지만 출력값은 본체객체(하위클래스)꺼가 나옴
ㄴ 본체 객체가 기준

ㄴ 선언과 동시에 초기화
ㄴ 향상된 for문
상위클래스 : 일반적인 개념
하위클래스 : 구체적인 개념
ㄴ 상위클래스가 더 작고 하위클래스가 더 크다
ㄴ 왜?
ㄴ 일반적인 개념은 공통된 내용이니까 작아야함
예시)
- 일반적인 개념
애니멀 클래스 : 동물 : 움직인다- 구체적인 개념
휴먼 클래스
새 클래스
호랑이 클래스
예시)

객체의 생성된 출처를 체크해보는 연산자
출처를 체크해보고 같은 출처이면 형변환 해줌
같은 출처여도 상위 -> 하위로 형변환시 출처가 불명확하다 인식하여 instanceof로 출처 체크해야 형변환이 됨
변수 instanceof 클래스명
예시)
c instanceof C : c라고 하는 참조변수가 가리키는 객체의 출처가 C클래스로 부터 만든 객체인가?
(객체의 포함관계)

c instanceof C
ㄴ c라는 참조변수 : 생성된 객체의 주소값
ㄴ 즉 c가 가리키는 객체가 C라는 클래스로부터 만들어진 객체인지 체크
c instanceof B c instanceof A
ㄴ C라는 객체 안에는 A, B객체가 포함되어 있음
ㄴ 포함된 자원이면 다 참이다

예시) 하위 -> 상위 객체로 형변환 시 출처 상관없이 instanceof로 출처 체크하고 형변환 해줘야 함

참고) instance
클래스라고 하는 객체 정의(존재x) -> new -> 힙공간에 존재 : 생성된 객체(인스턴스 객체)
- 생성과정이 있으면 instance 객체라고 한다
- 클래스는 객체 생성의 설계도에 불과함, 생성과정(new...)을 통해야지 힙 영역에 찐 객체가 됨(인스턴스 객체)
- instance == 객체