상속은 객체지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 기존 클래스(부모 클래스 또는 상위 클래스)의 속성과 메서드를 새로운 클래스(자식 클래스 또는 하위 클래스)가 물려받아 재사용하거나 확장할 수 있도록 하는 기능이다. 이를 통해 코드의 재사용성과 확장성을 높이고, 프로그램 구조를 체계적으로 설계할 수 있다.
Java에서 상속은 extends 키워드를 사용하여 구현한다.
class 부모클래스 {
// 부모 클래스의 필드와 메서드
}
class 자식클래스 extends 부모클래스 {
// 자식 클래스의 새로운 필드와 메서드 추가 가능
}
class Animal {
String name;
void eat() {
System.out.println(name + " is eating.");
}
}
class Dog extends Animal {
void bark() {
System.out.println(name + " is barking.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "Buddy";
dog.eat(); // 부모 클래스의 메서드 호출
dog.bark(); // 자식 클래스의 메서드 호출
}
}
다형성은 하나의 참조 변수로 여러 가지 타입의 객체를 참조할 수 있는 성질이다.
즉, 부모 클래스 타입의 참조 변수를 사용하여 자식 클래스 객체를 참조할 수 있다.
Animal animal = new Dog(); // 부모 타입 참조 변수로 자식 객체 참조
class Animal {
void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
void sound() {
System.out.println("Dog barks");
}
void bark() {
System.out.println("Dog-specific bark");
}
}
public class Main {
public static void main(String[] args) {
Animal animal = new Dog();
animal.sound(); // "Dog barks" 출력 (오버라이딩된 메서드 호출)
// animal.bark(); // 컴파일 에러: 부모 타입에 없는 메서드
}
}
출력:
Dog barks
class Animal {
Animal() {
System.out.println("Animal 생성자 호출");
}
}
class Dog extends Animal {
Dog() {
System.out.println("Dog 생성자 호출");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
출력:
Animal 생성자 호출
Dog 생성자 호출
super를 사용해 명시적으로 부모 생성자를 호출해야 한다.super()(즉, 매개변수가 없는 기본 생성자)를 자동으로 삽입합니다.super() 호출이 실패하므로, 컴파일 에러가 발생합니다.class Animal {
Animal(String name) {
System.out.println("Animal 생성자: " + name);
}
}
class Dog extends Animal {
Dog(String name) {
super(name); // 부모 생성자 호출
System.out.println("Dog 생성자: " + name);
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy");
}
}
출력:
Animal 생성자: Buddy
Dog 생성자: Buddy
오버라이드는 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것을 의미한다.
이를 통해 부모 클래스의 기본 동작을 자식 클래스의 요구에 맞게 변경할 수 있다.
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" 출력
}
}
super는 부모 클래스의 멤버(필드, 메서드, 생성자)를 참조하거나 호출할 때 사용된다.부모 클래스 생성자 호출:
class Animal {
Animal(String name) {
System.out.println("Animal 생성자: " + name);
}
}
class Dog extends Animal {
Dog(String name) {
super(name); // 부모 생성자 호출
System.out.println("Dog 생성자: " + name);
}
}
부모 클래스 메서드 호출:
class Animal {
void eat() {
System.out.println("Animal is eating");
}
}
class Dog extends Animal {
@Override
void eat() {
super.eat(); // 부모 메서드 호출
System.out.println("Dog is eating happily");
}
}
public: 어디서나 접근 가능.protected: 같은 패키지 및 자식 클래스에서 접근 가능.private: 상속은 가능하지만 직접 접근 불가.final로 선언되면 상속할 수 없다.final 메서드는 오버라이드할 수 없다.| 상속 | 조합(Composition) |
|---|---|
| "is-a" 관계를 나타냄 | "has-a" 관계를 나타냄 |
| 코드 재사용성이 높음 | 코드의 유연성이 높음 |
| 클래스 계층 구조가 복잡해질 수 있음 | 단순한 구조 유지 가능 |
상속은 코드 재사용과 확장을 가능하게 하며, 객체지향 프로그래밍에서 클래스 간 계층 구조 설계와 다형성 구현을 위한 강력한 도구이다.