extends
Bextends
"구분 | Has a | Is a |
---|---|---|
의미 | 포함 관계 | 상속 관계 |
관계 | 부품(구성) | 부모-자식 |
예 | Car has an Engine | Duck is a Bird |
키워드 | 멤버 변수 | extends |
모든 사물은 서로 조합되어 있다. (Has a)
클래스가 다른 클래스를 멤버로 보유한 관계
모든 사물은 서로 부모-자식 관계에 있다. (is a)
ex) Duck is a bird
src/
└── bird/
├── Bird.java
└── Duck.java
└── use/
└── UseBird.java
package bird;
public class Bird {
//멤버변수 정의 (속성만 정의됨, 동작은 없음)
public String color;
public int age;
//생성자 (초기화 동작을 정의함)
public Bird() {
System.out.println("🐦 Bird 생성됨");
}
public void fly() {
System.out.println("Bird가 난다");
}
}
잠깐! 자바스크립트는 생성자(constructor) 안에서 속성을 정의하잖아?
JavaScript와 Java는 생성자 역할이 비슷하지만, 속성 정의 위치와 초기화 방식이 다름
구분 Java JavaScript 멤버변수(속성) 정의 위치 클래스 블록 바깥에서 직접 정의 생성자( constructor
) 안에서 정의초기화 방법 (일반적으로)
멤버변수는 클래스 내에 선언만, 생성자에서 초기화생성자 안에서 바로 this.속성 = 값
예: name
정의String name;
(멤버 선언)this.name = "오리";
(생성자 내부)
package bird;
public class Duck extends Bird {
public Duck() {
System.out.println("🦆 Duck 생성됨");
}
public void quack() {
System.out.println("오리가 꽥꽥!");
}
}
(상속(
extends
)을 하더라도,
부모 클래스가 다른 패키지에 있으면import
가 반드시 필요함
같은 패키지에 있으면import
생략 가능)
package use;
import bird.Duck;
public class UseBird {
public static void main(String[] args) {
Duck d = new Duck();
d.color = "노란색"; // Bird에서 상속받은 멤버변수들
d.age = 2;
d.fly(); // 부모 Bird로부터 상속받은 메서드
d.quack(); // Duck 고유 메서드
}
}
출력결과:
🐦 Bird 생성됨
🦆 Duck 생성됨
Bird가 난다
오리가 꽥꽥!
parent 와 super
구분 개념 예시 관련 분야 관계 parent
GUI 트리 구조에서 부모 컨테이너를 의미 div.appendChild(img)
HTML / JS / GUI 프로그래밍 부모 요소 ↔ 자식 요소 super
상속 관계에서 부모 클래스를 의미 super();
orsuper.method()
자바 OOP (객체지향) 부모 클래스 ↔ 자식 클래스
- parent ↔ child
- super ↔ sub
super
는 "부모"를 가리키는 키워드
자식 클래스 안에서 부모의 생성자나 메서드를 사용하고 싶을 때 씀
super 키워드 용도 | 설명 |
---|---|
super() | 부모 클래스의 생성자를 호출 (생성자 맨 위에서만 사용 가능) |
super.변수명 | 자식 클래스와 이름이 겹치는 부모 변수 접근 시 사용 |
super.메서드() | 오버라이딩한 부모 메서드를 호출하고 싶을 때 사용 |
class Bird {
public Bird() {
System.out.println("🐦 Bird 생성됨");
}
public void fly() {
System.out.println("Bird가 난다");
}
}
class Duck extends Bird {
public Duck() {
super(); // 부모 생성자 먼저 호출
System.out.println("🦆 Duck 생성됨");
}
// @Override : 부모가 물려준 메서드를 자식 클래스에서
// "내 입맛에 맞게" 재정의
public void fly() {
super.fly(); // 부모의 fly() 호출
System.out.println("Duck이 낮게 난다");
}
}
→ 오버라이딩은 super
없이도 가능하고,
super.메서드()는 부모의 동작을 "함께" 쓰고 싶을 때만 사용
public class UseDuck {
public static void main(String[] args) {
Duck d = new Duck();
d.fly();
}
}
출력결과:
🐦 Bird 생성됨
🦆 Duck 생성됨
Bird가 난다
Duck이 낮게 난다
✅ 자바에서 super()
는 생략 가능
자식 클래스의 생성자에서 super()
를 명시하지 않으면,
컴파일러가 자동으로 부모의 기본 생성자(super()
)를 첫 줄에 삽입
(✅ JS에서는 super()
호출이 의무!)
구분 | 첫 번째 예제 | 두 번째 예제 |
---|---|---|
super() 호출 | ❌ 생략되어 있지만, 자동 호출됨 ( Bird 에 기본 생성자 있으므로 문제 없음) | ✅ super() 명시적으로 호출함 |
목적 | 부모 생성자 호출은 하지만 명시 X → 자동 처리 | 부모 생성자 호출을 명시 |
super.메서드() 사용 | ❌ 없음 | ✅ super.fly() → 부모의 메서드도 실행 |
오버라이딩 여부 | ❌ fly() 오버라이딩 안 함 → Bird의 메서드 그대로 사용 | ✅ fly() 오버라이딩 + 부모의 fly()도 호출 |
항목 | super() | super(매개변수) |
---|---|---|
호출 대상 | 부모의 기본 생성자 | 부모의 매개변수 있는 생성자 |
사용 위치 | 생성자의 첫 줄 | 생성자의 첫 줄 |
목적 | 부모 클래스의 기본 초기화 | 부모 클래스에 초기값 전달 |
생략 가능 여부 | 부모에 기본 생성자가 있으면 생략 가능 | ❌ 반드시 직접 호출해야 함 |
예시 코드 | super(); | super("오리"); |
사용 시기 | 기본값이면 충분할 때 | 부모 생성자에 특정 값 전달이 필요할 때 |
▼ 부모
class Bird {
Bird() { System.out.println("Bird 기본 생성자"); }
Bird(String name) { System.out.println("Bird: " + name); }
}
▼ 자식
class Duck extends Bird {
Duck() {
super(); // 기본 생성자 호출
}
Duck(String name) {
super(name); // 매개변수 생성자 호출
}
}
생성자에 매개변수가 있으면, 객체 만들 때도 무조건 거기에 맞게 값을 줘야 한다!