본문 바로가기
기초 및 언어/▶ Java&JSP

18. 상속

by 류딩이 2025. 8. 19.

상속이란?

  • 상속(Inheritance)은 기존 클래스(부모 클래스, Superclass)의 필드와 메서드를 새로운 클래스(자식 클래스, Subclass)가 물려받는 기능입니다.
  • 코드의 재사용성을 높이고, 클래스 간 계층 구조를 만들어 체계적인 관리가 가능합니다.
  • 자바는 단일 상속만 지원합니다. (즉, 하나의 클래스는 오직 하나의 부모만 가질 수 있음)

 

 

// 부모 클래스 (모든 클래스는 암묵적으로 Object를 상속받음)
class Sports {
	String name;   // 스포츠명
	int inwon;     // 인원수

	// 기본 생성자
	// 자식 클래스 생성 시 부모 생성자가 먼저 호출되는데,
	// 부모 클래스에 기본 생성자가 없으면 컴파일 에러 발생 → 반드시 작성
	public Sports() {}

	// 매개변수 있는 생성자
	public Sports(String name, int inwon) {
		this.name = name;
		this.inwon = inwon;
	}

	// 부모 클래스의 출력 메서드
	public void display1() {
		System.out.println("스포츠명: " + name);
		System.out.println("인원수 : " + inwon);
	}
}

// 자식 클래스: Baseball
class Baseball extends Sports {
	double ta; // 타율 (Baseball 고유 멤버)

	public Baseball(String name, int inwon, double ta) {
		// 부모의 멤버도 자식에서 직접 초기화 (권장: super(name, inwon))
		this.name = name;
		this.inwon = inwon;
		this.ta = ta;
	}

	// [오버라이딩 메서드]
	// - 부모와 동일한 메서드 이름, 반환형, 매개변수를 갖고 재정의
	// - 부모 기능 + 자식 고유 기능을 동시에 사용 가능
	@Override
	public void display1() {
		super.display1(); // 부모 메서드 실행
		System.out.println("타율   : " + ta);
	}
}

// 자식 클래스: Football
class Football extends Sports {
	int goal; // 골 수 (Football 고유 멤버)

	public Football(String name, int inwon, int goal) {
		// 부모 필드 초기화 + 자식 고유 필드 초기화
		this.name = name;
		this.inwon = inwon;
		this.goal = goal;
	}

	// 자식 고유 출력 메서드
	public void display3() {
		display1(); // 부모 메서드 호출
		System.out.println("골 수  : " + goal);
	}
}

public class Ex01_상속 {
	public static void main(String[] args) {
		// 부모 클래스 객체
		Sports s = new Sports("스포츠", 100);
		System.out.println("====== 부모의 display ======");
		s.display1();
		System.out.println();

		// 자식 클래스: Baseball
		Baseball b = new Baseball("야구", 9, 0.345);
		System.out.println("====== 부모의 display를 오버라이드 ======");
		b.display1();  // 자식에서 오버라이딩한 메서드 실행
		System.out.println();

		// 자식 클래스: Football
		Football f = new Football("축구", 11, 3);
		System.out.println("====== 부모의 display ======");
		f.display1();
		System.out.println("====== 자식의 display ======");
		f.display3();
	}
}

 

 

 

 

✅ 정리 한 줄

  • Sports → Baseball/Football 상속 구조로 공통 필드/메서드 재사용
  • Baseball: 부모 display1()을 오버라이딩해 확장
  • Football: 부모 메서드 그대로 쓰면서, 자식 고유 메서드 display3() 추가

1. 상속 (Inheritance)

  • extends 키워드를 사용하여 부모 클래스의 변수와 메서드를 자식이 물려받음
  • 자식은 부모 멤버 사용 가능, 하지만 부모는 자식 고유 멤버 사용 불가
  • 코드 재사용성과 유지보수성이 높아짐
  • 상속 받을 자식 클래스에 extends (부모 클래스명) 입력

2. 생성자 호출 규칙

  • 자식 객체 생성 시, 부모 생성자가 항상 먼저 호출
  • super(); 가 자동 삽입됨
  • 부모에 기본 생성자가 없다면, 기본 생성자 생성

3. 오버라이딩 (Overriding)

  • 부모 메서드와 이름, 매개변수, 반환형이 동일한 메서드를 자식이 재정의
  • 부모의 기능을 유지하면서 자식 고유 기능 추가 가능
  • @Override 애너테이션을 붙여주면 실수 방지 효과

4. 오버로딩 (Overloading) vs 오버라이딩 (Overriding)

구분 구분 오버로딩 (Overloading)  오버라이딩 (Overriding)
정의 같은 클래스 안에서 메서드 이름 동일, 매개변수 다름 부모-자식 관계에서 메서드 재정의
매개변수 다르게 정의 가능 반드시 동일해야 함
반환형 상관 없음 부모와 동일해야 함
관계 한 클래스 내부 상속 관계 필요

 

 

 

class Parent{
	int x = 10; 
	void method() {
		System.out.println("P_x : " + x);
		
	}
}

class Child extends Parent{ //부모 상속
	int x = 20; // 인스턴스변수 ) 초기화를 안히면 기본값이 들어감 / 부모와 변수가 같아도 괜찮다. 
	
	void method() {
		// 지역변수
		// 지역변수가 우선순위가 가장 높다. 우선출력
		// 지역변수 특징) Child 안에서만 실행된다. , 초기화를 시켜줘야함
		int x = 30; 
		System.out.println("지역변수_x :" + x); // 만약 지역변수가 없으면 인스턴스 변수가 실행된다.
		System.out.println("c_x :" + this.x); // 멤버변수 this.x 
		System.out.println("c_x :" + super.x); // 부모변수 super.x 
	}
}


public class Ex02_super {

	public static void main(String[] args) {
		Parent p = new Parent();
		p.method(); // Parent의 x출력
		
		Child c = new Child();
		c.method(); // Child의 x출력 + 출력했을때 본인(자식)것이 우선이됨
		
	}

}

 

 

📌 핵심 개념 정리

 변수의 우선순위

  • 같은 이름의 변수가 여러 레벨(지역, 인스턴스, 부모)에 존재할 경우
  • 지역변수 > 자식 인스턴스 변수 > 부모 인스턴스 변수 순서로 접근됨

 this 키워드

  • 현재 객체(자식 클래스)의 인스턴스 변수를 가리킴
  • this.x → Child의 멤버 변수 출력

 super 키워드

  • 부모 클래스의 멤버(변수, 메서드)에 접근할 때 사용
  • super.x → Parent의 멤버 변수 출력

 정리

  • 지역변수: 메서드 실행 시 가장 먼저 사용됨
  • 인스턴스 변수: 객체에 속한 변수, this로 접근 가능
  • 부모 변수: 자식에서 super 키워드로 접근

 

이 예제는 변수 이름이 중복될 때 **우선순위와 키워드(this, super)**의 의미를 한눈에 보여줍니다.

  • 지역변수가 가장 우선
  • this → 현재 객체(자식)의 변수
  • super → 부모의 변수

 


다단계 상속(멀티레벨 상속, multilevel inheritance)

 

class Person2{
	private String name;
	private int age;
	
	
	public Person2(){

	}
	

    public Person2(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void display() {
        System.out.println("name: " + name);
        System.out.println("age: " + age);
    }
}


class Worker extends Person2{ // Person의 name, age상속
	//	private String name;
	//	private int age;
	private String company;
	private String part;	
	
	
	// Worker 기본생성자 생성
	public Worker() { // 기본생성자 필수
		super();
	}
	public Worker(String name, int age, String company, String part) {
        super(name, age);          //
        this.company = company;
        this.part = part;       
	}
	@Override
	public void display() {
		super.display();
		System.out.println("company :" + company);
		System.out.println("part :" + part);
	}
}

// Teacher는 기본생성자가 있다.
class Teacher extends Worker { // 다중상속 : Worker 상속, person(name, age) + Worker(company, part) 상속
	//	private String name;
	//	private int age;
	//	private String company;
	//	private String part;
	private String subject;
	
	public Teacher(String name, int age, String company, String part, String subject) {
		super(name, age, company, part);
		this.subject = subject;
	}
	
	@Override
	public void display() { 
		super.display(); // worker의 display
		System.out.println("subject :" + subject);		
	}	
}

public class Ex04_상속 {

	public static void main(String[] args) {
		System.out.println("===== Person2 =====");
		 Person2 p = new Person2("제니", 30);
	     p.display();
	     
	     System.out.println("===== Worker (Person2를 상속받음) =====");
	     Worker w = new Worker("지수", 40, "메타빌드", "연구부");
	     w.display();
	     
	     System.out.println("===== Teacher (Worker를 상속받음)=====");
	     Teacher t = new Teacher("로제", 50, "메타고", "생활지도부", " 음악");
	     t.display();

	}

}

 

 

1. 상속 관계: Person2 → Worker → Teacher

Teacher는 Worker + Person2의 멤버를 모두 가짐

 

2. super()

자식 생성자에서 부모 생성자를 명시적으로 호출해야 부모의 멤버가 초기화됨

 

3. 오버라이딩(@Override)

부모와 동일한 메서드를 재정의하여, 자식 클래스에 맞는 출력 방식 구현 가능

 

4. 코드 재사용성

공통 부분(name, age)은 Person2(부모)에서 관리 → 중복 제거

 

 

 

'기초 및 언어 > ▶ Java&JSP' 카테고리의 다른 글

20. 제어자, 접근제어지시자(Access Modifier)와 기타제어자  (0) 2025.08.19
19. 포함  (0) 2025.08.19
17. 생성자  (2) 2025.08.18
16. setter/ getter  (2) 2025.08.18
15. 오버로딩  (1) 2025.08.18