[Java]Inheritance상속

Michelle Kim·2025년 4월 13일

Springboot-Java

목록 보기
17/20

Inheritance상속

1. 클래스를 상속해서 자식 클래스를 선언할 수 있다.
2. 자동 타입 변환, 강제 타입 변환, 다형성을 이해할 수 있다.
3. 클래스의 공통적인 특성을 추출해서 추상 클래스로 선언할 수 있다.

1. 상속

상속을 이용하면 부모 클래스의 수정으로 모든 자식 클래스들도 수정되는 효과를 가져오기 때문에 유지보수시간을 최소화할 수 있다.

🟠 클래스 상속

프로그램에서는 자식이 부모를 선택한다!
자식 클래스를 선언할때 어떤 부모 클래스를 상속받을 것인지 결정하고,
선택된 부모 클래스는 다음과 같이 extends뒤에 기술한다.

class 자식클래스 extends 부모클래스 {
	// 필드
    // 생성자
    // 메소드
    
class SportsCar extends Car{

}

🔷 <자바에서 상속의 특징>

  1. 여러개의 부모 클래스를 상속할 수 없다. extends 뒤에는 단 하나의 부모 클래스만 와야 한다.
  2. 부모 클래스에서 private접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외된다. 부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외된다.

🟠 부모 생성자 호출

super() : 부모의 기본 생성자를 호출한다. 반드시 자식 생성자 첫 줄에 위치해야한다.

직접 자식 생성자를 선언하고 명시적으로 부모 생성자를 호출하고 싶다면 다음과 같이 작성하면 된다.

자식클래스(매개변수선언, ...) {
	super(매개값, ...);
}
  • super(매개값 ...) 는 매개값의 타입과 일치하는 부모 생성자를 호출한다. 만약 매개값의 타입과 일치하는 부모 생성자가 없을 경우 -> 컴파일 에러가 발생

부모 클래스

public class People {
	public String name;
    public String ssn;
    
    public People(String name, String ssn){
    	this.name = name;
        this.ssn = ssn;
    }
}

자식 클래스

public class Student extends People{
	public int studentNo;
    
    public Student(String name, String ssn, int studentNo){
		super(name, ssn); // 부모 생성자 호출!
        this.studentNo = studentNo;
	}
}

🟠 메소드 재정의

메소드 재정의(Overriding): 상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야하는 경우 생김. => 자식 클래스에서 부모 클래스의 메소드를 다시 정의하는 것을 말한다.

🔷 메소드 재정의 방법

  • 부모의 메소드와 동일한 시그너처(리턴타입, 메소드 이름, 매개변수 목록)을 가져야 한다.
  • 접근 제한을 더 강하게 재정의할 수 없다. (부모 메소드 : public 접근 제한 가지고 있을때, 재정의하는 자식 메소드는 default/ private접근 제한으로 수정 불가능 !)
  • 새로운 에외(Exception)를 throws할 수 없다.

메소드가 재정의되었다면, 부모 객체의 메소드는 숨겨지기 때문에,
자식 객체에서 메소드를 호출하면 재정의된 자식 메소드가 호출 된다.

부모 클래스

public class Calculator{
	double areaCircle(double r){
    	System.out.println("Calculator 객체의 areaCircle() 실행");
        
        return 3.14519 * r * r;
    }
}

자식 클래스

public class Computer extends Calculator{
	@Override // 재정의
    double areaCircle(double r){
		System.out.println("Computer 객체의 areaCircle() 실행");
        return Math.PI * r * r;
    }
}

🔷 부모 메소드 호출

자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황 발생시, super키워드를 붙여서 부모 메소드를 호출할 수 있다.

super.부모메소드();

🟠 final 클래스와 final 메소드

final 키워드 : 클래스, 필드, 메소드를 선언할 때 사용할 수 있다. 해당 선언이 최종 상태이고 결코 수정될 수 없음을 뜻한다.

🔷 상속할 수 없는 final 클래스

클래스 선언할 때, final키워드를 class앞에 붙이면, 이 클래스는 최종적이 클래스이므로 상속할 수 없는 클래스가 된다. => 자식 클래스를 만들수 없다.

public final class Member{...}

상속할 수 없는 final클래스 : 상속 불가능!

public class VeryImportantPerson ~~extends Member~~ { }

🔷 재정의할 수 없는 final 메소드

메소드 선언할 때, final 키워드를 붙이면, 이 메소드는 최종적이 메소드이므로 재정의할 수 없는 메소드가 된다. => 자식 클래스에서 재정의할 수 없다.

2. 타입 변환과 다형성

다형성 : 사용 방법은 동일하지만 다양한 객체를 이용해서 다양한 실행 결과가 나오도록 하는 성질이다. ( ex: 자동차가 타이어를 사용하는 방법은 동일하지만, 어떤 타이어를 사용(장착)하느냐에 따라 주행 성능이 달라질 수 있다.)

  • 다향성을 구현하려면? : 메소드 재정의 + 타입변환이 필요하다!

🟠 자동 타입 변환

자동 타입 변환(promotion) : 클래스의 변환은 상속관계에 있는 클래스 사이에서 발생한다. 자식은 부모 타입으로 자동 타입 변환이 가능하다.

  • 자식은 부모의 특징과 기능을 상속받기 때문에, 부모와 동일하게 취급될 수 있다.
  • 예외) 메소드가 자식 클래스에서 재정의되었다면 자식 클래스의 메소드가 대신 호출 된다. => 재정의된 메소드는 타입 변환 이후에도 자식 메소드가 호출 된다!

🟠 필드의 다형성

왜 자동 타입 변환이 필요할까? 다형성을 구현하기 위해서! 필드의 타입을 부모타입으로 선언하면 다양한 자식 객체들이 저장될 수 있기 때문에 필드 사용 결과가 달라질 수 있다.

매개 변수의 다형성

🟠 강제 타입 변환

강제 타입 변환(casting) : 부모타입을 자식 타입으로 변환하는 것을 말한다.

  • 자식 타입이 부모 타입으로 자동 타입 변환한 후, 다시 자식 타입으로 변환할 때 강제 타입 변환을 사용할 수 있다.
Parent parent = new Child(); // 자동 타입 변환
Child child = (child) parent; //강제 타입 변화

🟠 객체 타입 확인

instanceof 연산자 : 어떤 객체가 어떤 클래스의 인스턴스인지 확인하기 위해 사용한다.

  • 연산자의 좌항에는 객체가 오고, 우항에는 타입이 온다.
  • 좌항의 객체가 우항의 인스턴스이면(우항의 타입으로 객체가 생성되었다면) => ture 리턴
boolean result = 좌항(객체) instanceof 우항(타입)

public void method(Parent parent) {
	if(parent instanceof Child) { // Child타입으로 변환이 가능한지 확인
    	Child = child = (child) parent;
    }
}

3. 추상 클래스

추상 클래스 : 클래스들의 공통적인 특성을 추출해서 선언한 클래스를 말한다.

  • 추상 클래스와 실체 클래스는 상속의 관계를 가진다.
  • 추상 클래스가 부모, 실체 클래스가 자식으로 구현 => 실체 클래스는 추상 클래스의 모든 특성을 물려받고, 추가적인 특성(필드, 메소드)을 가질 수 있다.
    ex) Animal - 추상클래스 / Bird, Insect, Fish - 실체 클래스 => 상속관계

🟠 추상 클래스의 용도

  1. 공통된 필드와 메소드의 이름을 통일할 목적
  2. 실체 클래스를 작성할 때 시간 절약

🟠 추상 클래스 선언

abstract키워드 : 클래스 선언에 붙인다.

  • abstract키워드 붙이면, new 연산자 이용해서 객체를 만들지 못하고, 상속을 통해 자식 클래스만 만들 수 있다!
  • new 연산자로 직접 생성자를 호출할 수는 없지만, 자식 객체가 생성될때 super(...)를 호출해서, 추상 클래스 객체를 생성하므로 추상 클래스도 생성자가 반드시 있어야 한다.
public abstrac class 클래스 {
	// 필드
    // 생성자
    // 메소드
}

🟠 추상 메소드와 재정의

추상 메소드 선언

public abstact class Animal{  // 추상 클래스
	public String kind;
    
    public void breathe(){
		System.out.println("숨을 쉽니다.");
}

	public abstract void sound(); // 추상 메소드
}
profile
🇬🇧영국대학교)Computer Science학과 졸업 📚Data, AI, Backend 분야에 관심이 많습니다. 👉Email: kimbg9876@gmail.com

0개의 댓글