자바의 상속(Inheritance)은 객체지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 기존 클래스(부모 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스)가 물려받아 재사용하거나 확장하는 기능을 제공한다. 이를 통해 코드 재사용성을 높이고 구조적이고 유지보수하기 쉬운 코드를 작성할 수 있다.
System.out.println("오리가 날개로 날아갑니다."); 같은 출력문을 사용하게 되면? 코드가 길어진다. 이를 해결하고 더 나아가 여러 오리가 '날다' 방식이 다르고 각 클래스의 고유의 행동을 구현하는 데에 필요한 방법이 '상속'이다.public class Main {
public static void main(String[] args) {
청둥오리 a청둥오리 = new 청둥오리();
a청둥오리.날다();
// 출력 : 오리가 날개로 날아갑니다.
흰오리 a흰오리 = new 흰오리();
a흰오리.날다();
// 출력 : 오리가 날개로 날아갑니다.
}
}
class 오리 {
void 날다() {
System.out.println("오리가 날개로 날아갑니다.");
}
}
class 흰오리 {
void 날다() {
System.out.println("오리가 날개로 날아갑니다.");
}
}
class 청둥오리 {
void 날다() {
System.out.println("오리가 날개로 날아갑니다.");
}
}
class 부모클래스 {
// 필드와 메서드
}
class 자식클래스 extends 부모클래스 {
// 부모의 필드와 메서드 상속
// 자식 클래스만의 새로운 필드와 메서드 추가 가능
}
예시코드
class Parent {} class Child extends Parent {} // 가능
예시코드
class GrandParent {} class Parent extends GrandParent {} class Child extends Parent {}
Object 클래스 상속: 자바의 모든 클래스는 암묵적으로 Object 클래스를 상속받는다. Object 클래스의 메서드(toString, equals, hashCode 등)를 재정의할 수 있다.
private 멤버는 상속되지 않음: 부모 클래스의 private 접근 제어자를 가진 필드나 메서드는 자식 클래스에서 접근할 수 없다. 하지만 간접적으로 사용할 수 있는 getter, setter 메서드는 상속받아 사용 가능하다.
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.sound(); // "Dog barks" 출력
}
}
class Parent {
String name = "Parent";
void display() {
System.out.println("Parent display");
}
}
class Child extends Parent {
String name = "Child";
void display() {
System.out.println("Child display");
}
void showParentInfo() {
System.out.println(super.name); // "Parent"
super.display(); // "Parent display"
}
}
class Parent {
Parent(String message) {
System.out.println("Parent Constructor: " + message);
}
}
class Child extends Parent {
Child() {
super("Hello from Parent!"); // 부모 클래스 생성자 호출
}
}
class Parent {
void greet() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
@Override
void greet() {
System.out.println("Hello from Child");
}
}
public class Main {
public static void main(String[] args) {
Parent obj = new Child();
obj.greet(); // "Hello from Child"
}
}
is-a 관계 확인: 상속은 "is-a" 관계를 만족해야 한다.
예: Dog is an Animal.
부모 클래스 변경의 영향: 부모 클래스 수정은 모든 자식 클래스에 영향을 줄 수 있으므로 신중히 해야 한다.
다중 상속의 대안: 다중 상속이 필요하다면 인터페이스를 활용할 수 있다.
상속 대신 조합 사용 고려: 상속은 강한 결합을 만드므로 필요 이상으로 의존성을 높일 수 있다. "상속보다는 조합(Composition)을 사용하라"는 원칙도 고려해야 한다.
| 특징 | 상속 | 인터페이스 |
|---|---|---|
| 관계 | is-a 관계 | can-do 관계 |
| 다중 구현 여부 | 단일 상속만 가능 | 다중 구현 가능 |
| 접근 제한자 | 부모 클래스의 접근 제어자 제한 적용 | 기본적으로 모든 메서드는 public |
| 구현 여부 | 부모 클래스의 구현 상속 | 구현 강제 (추상 메서드) |