상속
부모가 자식에게 물려주는 행위를 말함, 부모 클래스를 상위 클래스라고 부르고 , 자식 클래스를 하위 클래스 또는 파생 클래스라고 불린다.
class 자식 클래스 extends 부모클래스{
//필드
//생성자
//메소드
}
package p2;
public class App {
public static void main(String[] args) {
AAA refA=new AAA();
refA.fieldA1=30;
BBB refB=new BBB();
refB.fieldB1=40;
CCC refC = new CCC(); //
refC.fieldA1=10;
refC.methodA();
refC.methodC();
}
}
class AAA {
int fieldA1;
int fieldA2;
void methodA(){
System.out.println(("A의 메서드 호출됨"));
}
}
class BBB{
int fieldB1;
int fieldB2;
void methodB(){
}
}
///AAA는 CCC의 부모다 = AAA의 자식은 CCC이다. 부모자식관계
class CCC extends AAA{ //A를 상속받음 ==CCC는 AAA를 확장했기 때매 AAA호출 가능(메서드에서도)
int fieldC1;
int fieldC2;
int fieldA1; //중복 선언 가능 하지만! 진짜 최악 중에 최악!! ->이런식으로 코드짜면 안됨
//메모리가 5개 선언,중복된 메모리 2개있음
void methodC(){
System.out.println("C의 메서드 호출됨");
this.fieldA1=30; //중복선언 안됐을땐 부모에 있는 A임
//하지만 중복선언 됐을 시에 자식 A
super.fieldA1=40; //참조변수
//super키워드 나왔을땐 부모의 fieldA임
}
}

- 다중 상속 절대 안됨
- 모든 클래스들은 Object를 상속 받음
- 최상위 조상은 Object임 그래서 그냥 class AAA라고 보일지라도 class AAA extends Object이다!
- 변수를 중복 선언 가능한데 그럼 자식클래스 메소드가 호출된다
- 이를 위해 방지한게 super키워드!! 나왔을 땐 부모의 메소드가 호출된다
1. 다형성
다형성은 객체지향 프로그래밍(OOP) 의 중요한 특징 중 하나로, 부모 클래스 타입의 참조 변수로 자식 클래스의 인스턴스를 참조할 수 있도록 하는 기능이다.
즉, 하나의 부모 타입이 여러 자식 타입을 가질 수 있는 성질을 의미하며, 이는 코드의 확장성과 유연성을 높여준다.
package p3;
public class App {
public static void main(String[] args) {
//다형성(polymorphism)
//문법(컴파일) 런타임(실제 논리적 코드가 실행되는)
AAA refA = new AAA();
BBB refB = new BBB();
AAA refQQ = new BBB(); //다형성 문법
}
}
class AAA {
int fieldA1;
int fieldA2;
void methodA(){
System.out.println(("A의 메서드 호출됨"));
}
}
class BBB extends AAA{
int fieldB1;
int fieldB2;
void methodB(){
}
}
(1) AAA refA = new AAA();
- AAA 클래스 타입의 참조 변수 refA가 AAA 클래스의 인스턴스를 참조합니다.
- 즉, refA는 AAA의 모든 필드와 메서드를 사용할 수 있습니다.
(2) BBB refB = new BBB();
- BBB 클래스 타입의 참조 변수 refB가 BBB 클래스의 인스턴스를 참조합니다.
- refB는 BBB의 모든 필드(fieldB1, fieldB2)와 메서드(methodB), 그리고 AAA로부터 상속받은 fieldA1, fieldA2, methodA()를 사용할 수 있습니다.
(3) AAA refQQ = new BBB();
- 부모 타입(AAA)의 참조 변수 refQQ가 자식 클래스(BBB)의 인스턴스를 참조하는 것이 다형성 문법입니다.
- 하지만 refQQ는 부모 클래스의 멤버(필드, 메서드)만 접근 가능하며, BBB에서 추가된 필드(fieldB1, fieldB2)와 메서드(methodB())는 직접 사용할 수 없습니다.
특징
- 컴파일 타임에는 부모 타입을 따름
- AAA refQQ = new BBB();
- refQQ는 AAA 타입이므로, AAA에 정의된 필드와 메서드만 접근 가능.
- 런타임에는 실제 객체(BBB)의 메서드가 실행
- 만약 BBB에서 methodA()를 오버라이딩했다면, refQQ.methodA(); 실행 시 BBB의 methodA()가 호출됨.
- 부모클래스의 메서드만 사용할 수 있음 -> 형변환으로 사용 가능
주요 개념
- 부모 타입의 참조 변수로 자식 객체를 참조하기
- 자식 클래스의 객체를 부모 클래스 타입의 변수로 참조할 수 있습니다. 이때 자식 클래스의 오버라이딩된 메서드가 실행됩니다.
- 메서드 호출 시 실제 객체의 메서드가 호출됨
- 부모 클래스 타입으로 참조하더라도, 실제로는 자식 클래스의 메서드가 호출됩니다. 이것이 **동적 바인딩(dynamic binding)**이라고 불리며, 실행 시간에 메서드가 결정되는 특징이 있습니다.
2. 오버라이딩
오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 다시 재정의하는 것을 의미한다. 부모 클래스에서 정의된 메서드와 같은 시그니처(이름, 매개변수, 반환 타입)를 가진 메서드를 자식 클래스에서 구현하게 된다. 이때 자식 클래스에서 구현한 메서드는 부모 클래스의 메서드를 덮어쓰는 효과가 있다.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.sound(); // Dog barks (오버라이딩된 메서드 호출)
}
}
메모리 상에서 덮어쓰기
부모 클래스의 메서드가 호출될 때
- 부모 클래스에서 정의된 메서드가 호출될 경우, 자식 클래스에서 오버라이딩된 메서드가 있으면 그 메서드가 덮어씌워져서 실행됩니다.
- 이때 부모 클래스의 메모리 상에서 자식 클래스의 메서드로 대체된다고 생각할 수 있습니다.
- 원래 있던 부모 클래스의 메서드 기능은 더이상 사용되지 않음 대체 된다고 생각!!
오버라이딩을 사용하는 이유는 무엇일까?
오버라이딩을 사용하는 주된 이유는 **다형성(polymorphism)**과 유연한 코드 작성 때문이다.
- 다형성(polymorphism)
- 다형성을 통해 부모 클래스 타입의 참조 변수로 여러 자식 클래스의 객체를 다룰 수 있게 되기 때문에, 자식 클래스에서 오버라이딩된 메서드를 호출할 수 있는 것이다.
- 부모 클래스의 타입으로 여러 자식 객체를 다루게 되면, 각 자식 객체의 특성에 맞는 메서드가 실행되게 됨. 다양한 객체들이 동일한 방식으로 다뤄지면서도 서로 다른 동작을 할 수 있게 해주는 게 바로 다형성이다.
- 부모 클래스의 메서드 기능을 확장하기 위해
- 부모 클래스에서 기본적으로 제공하는 메서드가 있을 때, 그 메서드가 모든 자식 클래스에 적합하지 않거나 변경이 필요할 때 오버라이딩을 사용한다.
- 부모 클래스에서 정의된 메서드는 기본적인 행동만을 제공하고, 자식 클래스에서는 그 행동을 좀 더 구체적이고 특화된 방식으로 재정의할 수 있다.
- 이렇게 부모 클래스의 기능을 자식 클래스에 맞게 수정할 수 있기 때문에, 유연한 확장이 가능
- 구체적인 구현을 제공
- 부모 클래스에서 제공하는 기본적인 기능을 자식 클래스에서 특정한 방식으로 구현할 수 있다. 이렇게 하면, 기존 코드의 재사용성을 높이면서도 자식 클래스에 맞게 맞춤형 구현을 할 수 있디.
- 코드 유지보수성 향상
- 만약 자식 클래스가 부모 클래스의 메서드를 오버라이드하지 않으면, 모든 자식 클래스에서 부모 클래스의 동일한 메서드를 반복적으로 작성해야 할 수도 있다.
- 오버라이딩을 통해 부모 클래스에서 공통된 기능을 제공하고, 각 자식 클래스에서 세부 구현만 수정할 수 있으므로 코드 중복을 줄이고 유지보수를 쉽게 할 수 있다.
오버라이딩과 다형성은 상속과 밀접하게 연결되어 있기 때문에, 참조 변수와 인스턴스에 대해 각각 다르게 동작한다는 점을 이해하는 것이 매우 중요하다. 그리고 코드를 짤 때 두 가지를 함께 고려해야 한다.
오버라이딩과 다형성의 동작
- 문법(컴파일 시점)
- 컴파일 시점에서는 참조 변수의 타입이 중요
- 메서드를 호출할 때 어떤 메서드가 호출될지 참조 변수의 타입에 따라 결정
- 런타임(실행 시점)
- 실행 시점에서는 실제로 인스턴스(객체)의 타입이 중요
- 다형성 덕분에 참조 변수가 자식 클래스의 객체를 참조할 때, 실제 객체의 오버라이딩된 메서드가 호출
'중앙정보기술인재개발원 > JAVA' 카테고리의 다른 글
| [JAVA] 인터페이스 (0) | 2025.04.07 |
|---|---|
| [JAVA] Linked List (3) | 2025.04.01 |
| [JAVA] Depdency, DI, Composition, Aggregation (1) | 2025.03.26 |
| [JAVA] 싱글톤 (1) | 2025.03.24 |
| [JAVA] 메소드 (1) | 2025.03.21 |