상속은 기존에 정의된 클래스를 바탕으로 새로운 클래스를 정의할 수 있도록 해줍니다. 자식 클래스는 부모 클래스의 모든 멤버 변수와 메서드를 물려받지만, 생성자와 private 멤버는 상속되지 않습니다.
class Animal {
void eat() {
System.out.println("먹는다");
}
}
class Dog extends Animal {
void bark() {
System.out.println("짖는다");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // Animal 클래스에서 상속됨
dog.bark(); // Dog 클래스의 메서드
}
}
자바에서 클래스 상속은 extends 키워드를 사용합니다.
class 자식클래스 extends 부모클래스 {
// 자식 클래스의 멤버들
}
단일 상속만 지원 (하나의 부모 클래스만 상속 가능)
인터페이스를 통해 다중 상속의 효과를 일부 구현할 수 있음
부모 클래스의 멤버가 자식 클래스에서 어떻게 접근 가능한지는 접근 제어자에 따라 달라집니다.
|
접근 제어자 |
동일 클래스 |
같은 패키지 |
자식 클래스 |
전체 |
|---|---|---|---|---|
|
private |
O |
X |
X |
X |
|
default |
O |
O |
O (같은 패키지) |
X |
|
protected |
O |
O |
O |
X |
|
public |
O |
O |
O |
O |
상속을 받은 자식 클래스에서 부모 클래스의 메서드를 재정의할 수 있습니다. 이를 오버라이딩이라고 합니다.
class Animal {
void sound() {
System.out.println("동물이 소리를 낸다");
}
}
class Cat extends Animal {
@Override
void sound() {
System.out.println("야옹");
}
}
@Override 어노테이션을 사용하면 컴파일 타임에 재정의 여부를 체크할 수 있어 안정성이 높아짐
오버라이딩한 메서드는 부모 클래스가 아닌 자식 클래스의 메서드가 호출됨
supper는 부모 클래스의 생성자나 멤버에 접근할 때 사용합니다.
자식 클래스 생성자에서 부모 클래스 생성자를 명시적으로 호출할 수 있습니다.
class Animal {
Animal(String name) {
System.out.println("동물 이름: " + name);
}
}
class Dog extends Animal {
Dog() {
super("바둑이"); // 부모 생성자 호출
}
}
class Animal {
void eat() {
System.out.println("동물이 먹는다");
}
}
class Dog extends Animal {
void eat() {
super.eat(); // 부모 클래스의 eat() 호출
System.out.println("개가 사료를 먹는다");
}
}
생성자는 상속되지 않지만, 자식 클래스 생성자 내에서 부모 클래스의 생성자를 반드시 호출해야 함
명시하지 않으면 컴파일러가 super()를 자동으로 추가
부모 클래스에 기본 생성자가 없고 매개변수가 있는 생성자만 존재할 경우, 자식 클래스에서 super(인자)를 반드시 명시적으로 호출해야 함
final class: 상속이 불가능한 클래스
final method: 자식 클래스에서 오버라이딩 불가능한 메서드
final class Vehicle { }
// class Car extends Vehicle { } // 컴파일 오류
class Shape {
final void draw() {
System.out.println("그리기");
}
}
코드 재사용 가능
유지보수가 쉬움
프로그램의 구조가 계층적으로 정리됨
잘못된 상속 구조는 코드 복잡성 증가
상위 클래스에 의존하게 되어 유연성이 낮아질 수 있음
오용 시 코드 품질 저하 가능
class Person {
String name;
void introduce() {
System.out.println("안녕하세요. 제 이름은 " + name + "입니다.");
}
}
class Student extends Person {
String school;
@Override
void introduce() {
System.out.println("안녕하세요. 학생입니다. 이름은 " + name + ", 학교는 " + school + "입니다.");
}
}