Java_12) Inheritance - 상속
2025. 8. 27. 17:26

    <상속>

- 상속의 정의

**상속(Inheritance)**은 부모(상위) 클래스의 필드와 메서드를 자식(하위) 클래스가 물려받아 재사용하는 것이다. 객체 생성 시 부모 부분 → 자식 부분 순으로 메모리에 구성되며, 자식 객체 내부에 부모 객체가 존재하는 것처럼 실행된다.

- 상속의 장점

  1. 재사용성/생산성: 코드를 재사용하여 새로운 클래스를 정의할 수 있다
  2. 유지보수성: 공통 코드를 상위 클래스에 두어 변경이 용이하다
  3. 확장성: 하위 클래스에서 오버라이딩으로 동작을 재정의할 수 있다

- 상속의 특징

  • 단일 상속: 다중 상속은 불가능하다 (부모는 하나)
  • Object 클래스: 모든 클래스는 Object라는 최상위 클래스를 상속받는다
  • 접근 범위: 오버라이딩 시 접근 범위는 축소할 수 없다

ex: Man과 BusinessMan

- 부모 클래스: Man

package com.kh.inherit;

public class Man {
    private String name;
 
    protected Man() {
        super();
        System.out.println("Man의 기본생성자");
    }

    protected Man(String name) {
        super();
        this.name = name;
        System.out.println("Man에 name이 포함된 생성자");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    public void tellYourName() {
        System.out.println("My name is " + name);
    }
}

- 자식 클래스: BusinessMan

package com.kh.inherit;

public class BusinessMan extends Man {
    private String company;
    private String position;
    
    protected BusinessMan(String name, String company, String position) {
        super(name); // 자식클래스의 생성자에는 무조건 부모생성자가 필요
        // 맨 첫번째 줄에, 생략 시 부모의 기본 생성자를 호출
        this.company = company;
        this.position = position;
    }
    
    public void tellYourInfo() {
        System.out.println("My company is " + company);
        System.out.println("My Position is " + position);
        super.tellYourName();  // super. -> 부모클래스의 메모리에 접근
    }
}

- super 키워드의 활용

super 키워드는 부모 클래스의 요소에 접근할 때 사용한다:

  • super(): 부모 클래스의 생성자 호출
  • super.method(): 부모 클래스의 메서드 호출
  • super.field: 부모 클래스의 필드 접근

Product 상속 구조 - 제품 관리 시스템

- 부모 클래스: Product

package com.kh.inherit;

public class Product {
    private String pName;
    private int price;
    private String brand;
    
    protected Product() {
        super();
    }
    
    protected Product(String pName, int price, String brand) {
        super();
        this.pName = pName;
        this.price = price;
        this.brand = brand;
    }
    
    // Getter, Setter 메서드들
    public String getpName() {
        return pName;
    }
    
    public void setpName(String pName) {
        this.pName = pName;
    }
    
    public int getPrice() {
        return price;
    }
    
    public void setPrice(int price) {
        this.price = price;
    }
    
    public String getBrand() {
        return brand;
    }
    
    public void setBrand(String brand) {
        this.brand = brand;
    }
    
    // 제품 정보 출력 메서드
    public String inform() {
        return "상품명 : " + pName + " / 가격 : " + price + " / 브랜드 : " + brand; 
    }
}

- 자식 클래스: Desktop

package com.kh.inherit;

public class Desktop extends Product {
    private boolean isAllInOne;
    
    public Desktop() {
        // 부모의 기본 생성자가 자동 호출
    }

    public Desktop(String pName, int price, String brand, boolean isAllInOne) {
        super(pName, price, brand); // 부모 생성자 명시적 호출
        this.isAllInOne = isAllInOne;
    }

    public boolean isAIO() {
        return isAllInOne;
    }

    public boolean isAllInOne() {
        return isAllInOne;
    }

    public void setAllInOne(boolean isAllInOne) {
        this.isAllInOne = isAllInOne;
    }
    
    // 오버라이딩: 부모의 inform() 메서드를 재정의
    public String inform() {
        return "상품명 : " + super.getpName() + " / 가격 : " + super.getPrice() + 
               " / 브랜드 : " + super.getBrand() + " / 일체형 여부 : " + 
               (isAllInOne ? "일체형" : "따로따로"); 
    }
}

- 자식 클래스: TV

package com.kh.inherit;

public class TV extends Product {
    private int inch;

    public TV() {
        super(); // 부모의 기본 생성자 호출
    }

    public TV(String pName, int price, String brand, int inch) {
        super(pName, price, brand); // 부모의 매개변수 생성자 호출
        this.inch = inch;
    }

    public int getInch() {
        return inch;
    }

    public void setInch(int inch) {
        this.inch = inch;
    }
    
    // TV 클래스는 부모의 inform() 메서드를 그대로 사용
}

상속 실행 및 테스트

- 상속 관계 테스트

package com.kh.inherit;

import java.util.Scanner;

public class Run {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        // Man 객체 생성
        Man m1 = new Man("IAhn");
        
        // BusinessMan 객체 생성
        BusinessMan m2 = new BusinessMan("IAhn", "hth_sm", "dancer");
        m2.tellYourInfo();
        m2.tellYourName(); // 부모 클래스의 메서드 호출
        
        // 잘못된 할당 (컴파일 에러)
        // BusinessMan m3 = new Man(); // 자식의 참조변수에 부모객체를 생성할 수는 없다
        
        // Product 상속 구조 테스트
        Desktop d1 = new Desktop();
        Desktop d2 = new Desktop("d-100", 1000000, "samsung", true);
        TV t1 = new TV("t-100", 1000000, "samsung", 14);
        
        System.out.println(t1.inform());  // 부모의 inform() 메서드 사용
        System.out.println(d2.inform());  // 오버라이딩된 inform() 메서드 사용
    }
}

실행 결과:

Man에 name이 포함된 생성자
Man에 name이 포함된 생성자
My company is hth_sm
My Position is dancer
My name is IAhn
상품명 : t-100 / 가격 : 1000000 / 브랜드 : samsung
상품명 : d-100 / 가격 : 1000000 / 브랜드 : samsung / 일체형 여부 : 일체형

    <오버라이딩>

- 오버라이딩의 정의

**오버라이딩(Overriding)**은 부모 클래스에 있는 메서드를 하위 클래스에서 내용만 재정의하는 것이다.

- 오버라이딩의 조건

  1. 메서드 이름: 부모와 동일해야 한다
  2. 매개변수: 타입, 개수, 순서가 모두 동일해야 한다
  3. 반환형: 부모와 동일하거나 하위 타입이어야 한다
  4. 접근 제한자: 부모보다 좁은 범위로 변경할 수 없다

- 오버라이딩 vs 오버로딩

구분 오버라이딩(Overriding) 오버로딩(Overloading)

관계 상속 관계 같은 클래스 내
메서드명 동일 동일
매개변수 동일 다름
목적 기능 재정의 기능 확장

상속에서의 생성자 호출 순서

- 생성자 호출 메커니즘

public class InheritanceTest {
    public static void main(String[] args) {
        System.out.println("=== BusinessMan 객체 생성 ===");
        BusinessMan bm = new BusinessMan("김개발", "테크회사", "개발자");
    }
}

실행 과정:

  1. BusinessMan 생성자 호출
  2. super(name) → Man 생성자 호출
  3. Man 생성자에서 super() → Object 생성자 호출 (자동)
  4. Object → Man → BusinessMan 순으로 객체 구성 완료

- 메모리 구조

[BusinessMan 객체]
├── [Man 부분]
│   ├── name: "김개발"
│   └── tellYourName() 메서드
├── company: "테크회사"
├── position: "개발자"
└── tellYourInfo() 메서드

  1. 상속은 부모 클래스의 필드와 메서드를 자식 클래스가 재사용하는 메커니즘이다
  2. extends 키워드를 사용하여 상속 관계를 설정한다
  3. super 키워드를 통해 부모 클래스의 생성자와 메서드에 접근할 수 있다
  4. 오버라이딩을 통해 부모 메서드의 동작을 재정의할 수 있다
  5. 자식 클래스 생성 시 부모 생성자가 먼저 호출된다

 

'Java' 카테고리의 다른 글

Java_14) Garbage Collection  (1) 2025.11.11
Java_13) 오버로딩과 오버라이딩  (0) 2025.11.10
Java_11) Access Modifier, ObjectArray  (1) 2025.08.27
Java_10) Class - 객체 (Object)  (4) 2025.08.27
Java_09) Method  (4) 2025.08.27