티스토리 뷰
자바 - 상속 ( 클래스 상속, 메서드 오버라이딩, super, final 클래스 및 메서드의 상속, 자동/강제 타입 변환, 다형성, instanceof, 추상 클래스 )
Kodong's blog 2026. 3. 8. 11:00이번 포스팅은 상속에 대한 글이다.
이 상속 개념을 똑바로 잡지 않은 상태에서 작년 9월에서 10월 사이쯤에 체스게임을 만들었었는데,
지금 보니까 코드가 매우 엉망이다..
일단 이 상속이라는 개념은 이미 잘 개발된 클래스를 재사용해서 새로운 클래스를 만들기 때문에 중복되는 코드를 줄여 개발 시간을 단축시켜준다.
그러니 잘 알면 알수록 이득이다.
🟩 클래스 상속
⭐️⭐️ 다른 언어와 달리, 자바에서 클래스는 다중 상속을 허용하지 않는다. ⭐️⭐️
public class ChildClass extends ParentClass1, ParentClass2 {
}
// --> XXX
아래와 같이 Parent를 상속하는 Child 클래스가 있다고 하자.
public class Child extends Parent {
}
이때, 아래와 같이 자식 객체를 생성하면 부모 객체가 먼저 생성된 다음에 자식 개체가 생성된다.
Child child = new Child();
모든 객체는 생성자를 호출해야만 생성된다. 부모 객체도 예외는 아니다.
그렇다면 부모 객체의 생성자는 어디서 호출된 것일까?
부모 생성자는 자식 생성자의 맨 첫 줄에 숨겨져 있는 super()에 의해 호출된다.
public Child {
public Child() {
super();
// ...
}
}
super()는 컴파일 과정에서 자동으로 추가된다.
super()에 대한 내용은 아래 포스팅을 참고하자.
https://kodong8774.tistory.com/121
자바 - super, super() 정리, 활용 예제
그다음으로는 super 키워드를 이용한 예제를 만들어보자.일단 먼저 super 키워드의 의미부터 간단하게 정리하겠다. 1. super → 부모 클래스의 멤버에 접근 할 때2. super() → 부모 클래스의 생성자를
kodong8774.tistory.com
🟩 메소드 재정의 (메소드 오버라이딩)
메소드를 오버라이딩하는 내용은 아래 글에 정리해좋았다.
https://kodong8774.tistory.com/127
자바 - 오버라이딩 개념 및 예제
스프링 부트로 상품 관리 서버를 만들던 중, 리스트(DB는 아직..)에 저장되어 있는 Product를 update하는 중이었다.이때, indexOf()를 사용해서 기존 리스트에 있던 Product의 인덱스를 가져오는 코드를 짜
kodong8774.tistory.com
🟩 부모 메서드 호출
메소드를 재정의하면, 부모 메소드는 숨겨지고, 자식 메소드만 사용되기 때문에, 비록 부모 메서드의 일부만 변경된다 하더라도 중복된 내용을 자식 메소드도 가지고 있어야한다.
예를 들어, 부모 메소드가 100줄의 코드를 가지고 있을 경우, 자식 메소드에서 1줄만 추가하고 싶더라도, 100줄의 코드를 자식 메소드에서 다시 작성해야한다.
이 문제는 자식 메소드 내에서 부모 메소드를 호출하면 쉽게 해결할 수 있다.
이때, super 키워드와 도트(.) 연산자를 사용하면 숩겨진 부모 메소드를 호출할 수 있다.
class Parent {
public void methoed() {
// 작업 처리1
}
}
class Child extends Parent {
@Overide
public void method() {
super.method();
// 작업 처리2
}
}
이 방법은 부모 메서드를 재사용함으로써, 자식 메소드의 중복 작업 내용을 없애는 효과를 가져온다.
🟩 final 클래스와 final 메소드
🔵 final 클래스
클래스를 선언할 때 final 키워드를 class 앞에 붙이면 최종적인 클래스이므로, 더 이상 상속할 수 없는 클래스가 된다.
즉, final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다.
🔵 final 메소드
메소드 선언할때, final 키워드를 붙이면 이 메소드는 최종적인 메소드이므로 오버라이딩할 수 없는 메소드가 된다.
즉, 부모 클래스를 상속해서 자식 클래스를 선언할 때, 부모 클래스에 선언된 final 메소드는 자식 클래스에서 재정의할 수 없다.
🟩 자동 타입 변환
기본 타입의 변환과 마찬가지로, 클래스도 타입 변환이 있는데,
클래스의 타입 변환은 상속 관계에 있는 클래스 사이에서 발생한다.
여기서 자동 타입 변환(Promotion)은 아래와 같은 조건에서 자동적으로 타입 변환이 일어나는 것을 말한다.
부모 타입 변수 = 자식 타입 객체;
( 자식 타입 객체가 부모 타입으로 자동 타입 변환이 일어나는 것. )
또 자동 타입 변환은 바로 위의 부모가 아니더라도, 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있다.
아래는 자동 타입 변환의 예시이다.
( 상속관계 )
A
↓ -- ↓
B D
↓ ↓
C E
class A {
}
class B extends A {
}
class D extends A {
}
class C extends B {
}
class E extends D {
}
class Main {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
E e = new E();
A a1 = b;
A a2 = d;
A a3 = c;
A a4 = e;
B b1 = c;
D d1 = e;
// B b2 = e; 컴파일 에러(상속관계에 있지않음)
// D d2 = c; 컴파일 에러(상속관계에 있지않음)
}
}
여기서 중요한 포인트가 있다.
부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능하다.
비록 변수는 자식 객체를 참조하지만, 변수로 접근 가능한 멤버는 부모 클래스 멤버로 한정된다.
하지만, 자식 클래스에서 오버라이딩된 메소드가 있다면, 해당 메소드는 부모 메소드 대신 오버라이딩 된 메소드가 호출된다.
🟩 강제 타입 변환
자식 타입은 부모 타입으로 자동 변환되지만, 반대로 부모 타입은 자식 타입으로 자동 변환되지 않는다.
따라서 우리는 캐스팅 연산자로 강제 타입 변환(Casting)을 할 수 있다.
<자식 타입> 변수 = (<자식 타입>) 부모타입객체;
강제 타입 변환은 자식 객체가 부모 타입으로 자동 변환된 후, 다시 자식 타입으로 변환할 때 강제 타입 변환을 사용할 수 있다.
Parent parent = new Child(); // 자동 타입 변환
Child child = (Child) parent; // 강제 타입 변환
자식 객체가 부모 타입으로 자동 변환되면, 부모 타입에 선언된 필드와 메소드만 사용가능하다는 제약 사항이 따른다.
만약 자식 타입에 선언된 필드와 메소드를 꼭 사용해야한다면 강제 타입 변환을 해서 다시 자식 타입으로 변환해야한다.
+)
작년에 체스게임을 만들때 이 부분에 대해서 간단하게 공부하고, 사용했던 적이 있다.
https://kodong8774.tistory.com/152
instanceof 및 다운 캐스팅 활용 - 부모 클래스와 자식 클래스 공통 메서드 문제 - 부모 타입의 배열
문제 상황부터 이해해보자.private Tile[][] gameTiles = new Tile[16][9];이렇게 부모 타입인 Tile배열이 있다고 하자.이 배열에는 자식 클래스인 MonsterTile, TowerTile, EmptyTile이 있다. ( ↓ : 자식 클래스들 )public
kodong8774.tistory.com
이제 다형성에 대해서 이야기 해보자.
🟩 다형성
자바에서 다형성은 한 타입의 참조 변수를 통해 여러 타입의 객체를 참조할 수 있도록 하는 것이다.
즉, 상위 클래스 타입의 참조 변수를 통해서 하위 클래스의 객체를 참조할 수 있도록 허용하여 상위 클래스가 동일한 메시지로 하위 클래스들이 서로 다른 동작을 할 수 있도록 한다.
아주 쉽게 말해서, 사용 방법은 동일하지만, 실행 결과가 다양하게 나오는 성질을 말한다.
다형성을 구현하기 위해서는 자동 타입 변환과 메소드 오버라이딩이 필요하다.
예시를 들어보자.
한국 타이어와 금호 타이어는 모두 타이어를 상속하고 있을 것이다.
그렇다면 한국 타이어와 금호 타이어는 타이어(부모)의 메소드를 동일하게 가지고 있다고 말할 수 있다.
만약 한국 타이어와 금호 타이어가 타이어(부모)의 메소드를 오버라이딩하고 있다면,
타이어 메소드 호출 시 오버라이딩된 메소드가 호출된다.
오버라이딩된 내용은 두 타이어가 다르기 때문에 실행 결과가 다르게 나온다.
즉, 동일한 메소드를 가지고 있지만(= 객체 사용방법이 동일), 실행 결과는 다르게 나오는 것이다.
이것이 바로 다형성이다.
아래 예제를 참고하자. ( 다형성을 이해하기에 좋은 예제라고 생각한다!)
class Tire {
public void roll() {
System.out.println("회전합니다");
}
}
class Hankooktire extends Tire {
@Override
public void roll() {
System.out.println("한국 타이어가 회전합니다");
}
}
class KumhoTire extends Tire {
@Override
public void roll() {
System.out.println("금호 타이어가 회전합니다");
}
}
class Car {
public Tire tire;
public void run() {
tire.roll();
}
}
class Main {
public static void main(String[] args) {
Car car = new Car();
car.tire = new Tire();
car.run();
car.tire = new Hankooktire();
car.run();
car.tire = new KumhoTire();
car.run();
}
}
🟩 객체 타입 확인 (instanceof)
매개변수의 다형성과 같은 상황에서 유용하게 사용할 수 있는 instanceof 연산자에 대해서 이야기해보자.
예를 들어, Parent 클래스를 상속하고 있는 Child 클래스가 있다고 하자.
Parent var = new Child();
이때 각각 용어 정리를 하자면,
- 변수 타입 (reference type) → Parent
- 실제 객체 타입 (actual object type / runtime type) → Child
boolean result = 객체 instanceof 타입;
instanceof 연산자의 좌항에는 객체가 오고, 우항에는 타입이 오는데,
좌항의 객체가 우항의 타입이면 true를 산출하고, 그렇지 않으면 false를 산출한다.
variable instanceof Parent
이때, instanceof는 변수 타입이 아닌, 변수가 참조하는 실제 객체 타입을 검사한다.
즉, 위의 예시로 들자면,
variable이 참조하는 객체가 Parent의 인스턴스(Parent 또는 Parent의 자식 클래스 객체)인가?
를 검사한다.
아래는 매개변수의 다형성의 예시이다.
parent가 Child1의 객체를 참조하고 있을 때만, 해당 로직을 실행하는 것이다.
public void tmpMethod(Parent parent) {
if (parent instanceof Child1) {
Child1 child = (Child1) parent;
// ...
}
}
🟩 추상 클래스
이에 대한 부분은 아래 포스팅에서 다루었다.
https://kodong8774.tistory.com/117
자바 - 추상 클래스 개념 정리
자바에서, 추상 클래스를 언제 사용하는지는 체스 게임을 만들면서 공부를 해놓고, 이후, 제대로 추상 클래스, super키워드를 활용해본적이 없는 것 같아 오늘 혼자서 추상클래스, super 키워드로
kodong8774.tistory.com
------------------
여기까지..
작년 가을에 도전했었던 체스게임을 다시 시도해볼까 생각중이다....
'Java' 카테고리의 다른 글
| 자바 - (추후 내용 추가 및 수정 하자!) 중첩 선언과 익명 객체 (중첩 클래스, 중첩 인터페이스, 익명 객체) (0) | 2026.03.15 |
|---|---|
| 자바 - 인터페이스 ( 상수 필드, 추상 메서드, 디폴트 메서드, 정적 메서드, private 메서드, 다중 인터페이스 ) (0) | 2026.03.09 |
| 자바 - 싱글톤 패턴(Singleton pattern) (0) | 2026.03.06 |
| 자바 - 생성자 오버로딩, this(), 가변길이 매개변수, 메서드 오버로딩, final 필드와 상수, 패키지 (0) | 2026.03.06 |
| 자바 - 참조타입, 메모리 사용 영역, 타입에 따른 배열 기본값, main()메소드의 String[] 매개변수 용도 (0) | 2026.03.03 |