상속(1)

heeezni·2025년 5월 14일
0

Java 문법

목록 보기
8/14
post-thumbnail

상속 (Inheritance)

  • Is a 관계
  • OOP에서는 여러 클래스 사이에서 공통되는 코드(속성, 기능)을 한 번만 정의하고, 재사용 할 수 있도록 '상속'이라는 기능 제공
  • A is a B → class A extends B
    "상속 관계"를 표현하는 자바 문법 "extends"
구분Has aIs a
의미포함 관계상속 관계
관계부품(구성)부모-자식
Car has an EngineDuck is a Bird
키워드멤버 변수extends
  • 모든 사물은 서로 조합되어 있다. (Has a)
    클래스가 다른 클래스를 멤버로 보유한 관계

  • 모든 사물은 서로 부모-자식 관계에 있다. (is a)
    ex) Duck is a bird

Java - Duck is a bird 🦆 (1)

패키지 구조

src/
└── bird/
├── Bird.java
└── Duck.java
└── use/
└── UseBird.java

Bird.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는 생성자 역할이 비슷하지만, 속성 정의 위치와 초기화 방식이 다름

구분JavaJavaScript
멤버변수(속성) 정의 위치클래스 블록 바깥에서 직접 정의생성자(constructor) 안에서 정의
초기화 방법(일반적으로)
멤버변수는 클래스 내에 선언만, 생성자에서 초기화
생성자 안에서 바로 this.속성 = 값
예: name 정의String name; (멤버 선언)this.name = "오리"; (생성자 내부)

멤버변수 (속성) 초기화 방법

Duck.java (자식 클래스)

package bird;

public class Duck extends Bird {
	public Duck() {
        System.out.println("🦆 Duck 생성됨");
    }

    public void quack() {
        System.out.println("오리가 꽥꽥!");
    }
}

(상속(extends)을 하더라도,
부모 클래스가 다른 패키지에 있으면 import가 반드시 필요함
같은 패키지에 있으면 import 생략 가능)

UseBird.java (main 실행 클래스)

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

구분개념예시관련 분야관계
parentGUI 트리 구조에서 부모 컨테이너를 의미div.appendChild(img)HTML / JS / GUI 프로그래밍부모 요소 ↔ 자식 요소
super상속 관계에서 부모 클래스를 의미super(); or super.method()자바 OOP (객체지향)부모 클래스 ↔ 자식 클래스
  • parent ↔ child
  • super ↔ sub

super( )

super는 "부모"를 가리키는 키워드
자식 클래스 안에서 부모의 생성자나 메서드를 사용하고 싶을 때 씀

super 키워드 용도설명
super()부모 클래스의 생성자를 호출 (생성자 맨 위에서만 사용 가능)
super.변수명자식 클래스와 이름이 겹치는 부모 변수 접근 시 사용
super.메서드()오버라이딩한 부모 메서드를 호출하고 싶을 때 사용

Java - Duck is a bird 🦆 (2)

부모클래스 Bird.java

class Bird {
    public Bird() {
        System.out.println("🐦 Bird 생성됨");
    }
    public void fly() {
        System.out.println("Bird가 난다");
    }
}

자식클래스 Duck.java

class Duck extends Bird {
    public Duck() {
        super(); // 부모 생성자 먼저 호출
        System.out.println("🦆 Duck 생성됨");
    }

    // @Override : 부모가 물려준 메서드를 자식 클래스에서 
    // "내 입맛에 맞게" 재정의
    public void fly() {
        super.fly(); // 부모의 fly() 호출
        System.out.println("Duck이 낮게 난다");
    }
}

→ 오버라이딩은 super 없이도 가능하고,
super.메서드()는 부모의 동작을 "함께" 쓰고 싶을 때만 사용

실행클래스 UseDuck.java

public class UseDuck {
    public static void main(String[] args) {
        Duck d = new Duck();
        d.fly();
    }
}

출력결과:
🐦 Bird 생성됨
🦆 Duck 생성됨
Bird가 난다
Duck이 낮게 난다

✅ 자바에서 super()는 생략 가능

자식 클래스의 생성자에서 super()를 명시하지 않으면,
컴파일러가 자동으로 부모의 기본 생성자(super())를 첫 줄에 삽입

(✅ JS에서는 super() 호출이 의무!)

Duck is a Bird 예제 1과 예제 2 비교

구분첫 번째 예제두 번째 예제
super() 호출❌ 생략되어 있지만, 자동 호출됨
(Bird에 기본 생성자 있으므로 문제 없음)
super() 명시적으로 호출함
목적부모 생성자 호출은 하지만 명시 X
→ 자동 처리
부모 생성자 호출을 명시
super.메서드() 사용❌ 없음super.fly() → 부모의 메서드도 실행
오버라이딩 여부fly() 오버라이딩 안 함 → Bird의 메서드 그대로 사용fly() 오버라이딩 + 부모의 fly()도 호출

super(매개변수)

항목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); // 매개변수 생성자 호출
    }
}

생성자에 매개변수가 있으면, 객체 만들 때도 무조건 거기에 맞게 값을 줘야 한다!

profile
아이들의 가능성을 믿었던 마음 그대로, 이제는 나의 가능성을 믿고 나아가는 중입니다.🌱

0개의 댓글