💡상속(Inheritance)
1. 상속의 개념 및 사용
- OOP 특징 중 하나이며, 기존의 클래스에 추가하거나 재정의하여 새로운 클래스를 정의하는 것을 의미한다.
- 자식 클래스가 부모 클래스를 상속받으면 부모 클래스의 필드와 메서드들을 모두 사용할 수 있다. 현실 세계에 비유하자면 '부모의 유전자 또는 재산을 자식이 상속받아 사용한다'.라고 생각해면 쉽게 이해할 수 있다.
- 부모클래스(Parent Class)는 상위 클래스(Super Class), 기본 클래스(Base Class)라고도 불린다.
- 자식클래스(Child Class)는 하위 클래스(Sub Class), 파생 클래스(Derived Class)라고도 불린다.
- 자식은 부모의 모든 멤버(변수, 메소드)를 상속받는다. (단, private는 제외)
- 클래스 상속을 위해서는 extends 키워드 사용한다.
class Person {
String name;
void setName(String name) {
this.name = name;
}
}
class Student extends Person{
void print() {
System.out.println("나의 이름은 " + this.name + "입니다.");
}
}
public class Test {
public static void main(String[] args) {
Student st = new Student();
st.setName("홍길동");
st.print(); // output: 나의 이름은 홍길동 입니다
}
}
2. 상속의 장점
- 기존에 작성된 클래스를 재사용할 수 있다.
- 코드의 중복을 줄일 수 있다.
- 클래스 간의 계층적 관계를 구성함으로써 문법적 토대를 마련한다.
- 신뢰성 있는 소프트웨어를 손쉽게 개발, 유지보수할 수 있다.
3. 단일 상속 vs 다중 상속
다른 언어에서는 다중 상속이 가능한 언어들도 있지만 기본적으로 자바는 단일 상속만 가능하다. 즉, 다중 상속이 불가능하다. 따라서 extends키워드를 사용할 때 한 개의 부모 클래스만 존재할 수 있다. 하지만 코딩을 하다 보면 다중 상속이 필요할 때도 있다. 이럴 경우 implements키워드를 사용하여 다중 상속을 구현할 수 있다.
4. IS-A 관계 vs Has-A 관계
상속관계가 있는 클래스들은 자식 클래스 is-a 부모 클래스 관계로 정의될 수 있다. 예를 들어 Student is a Person 학생은 사람이다라는 말과 같이 말할 수 있는 관계를 IS-A관계라고 한다.
그와 반대로 Has-A관계는 포함관계를 뜻하며, 한 클래스의 멤버로 다른 클래스를 선언해서 부품처럼 조립하여 사용하는 걸 말한다. 즉 객채형 참조 변수로 사용된다.
5. Super와 Super()
this와 this()처럼 상속 관계에서는 super와 super()가 존재한다.
super 키워드는 부모 클래스로부터 상속받은 필드나 메서드를 자식 클래스에서 참조하는 데 사용하는 참조 변수이다. 즉, super키워드를 사용하면 부모 클래스의 멤버를 사용할 수 있다.
class Person {
String name;
int age;
void setName(String name) {
this.name = name;
}
void setAge(int age) {
this.age = age;
}
}
class Student extends Person{
void print() {
System.out.println("나의 이름은 " + super.name + "이고, 나이는 " + super.age + "살 입니다.");
}
}
public class Test {
public static void main(String[] args) {
Student st = new Student();
st.setName("홍길동");
st.setAge(20);
st.print(); // output: 나의 이름은 홍길동이고, 나이는 20살입니다.
}
}
super()는 부모 클래스의 생성자를 호출할 경우 사용된다. 직접 작성하지 않아도 자바는 컴파일시 해당 키워드를 자동으로 추가해 준다. 하지만 부모클래스에 기본생성자가 없고, 매개변수가 있는 생성자를 생성하면 자동으로 적용되지 않으며, 이 때 자식 클래스의 생성자가 부모클래스를 호출하면 오류가 난다. 그렇기 때문에 기본 생성자는 명시적으로 작성해주는 것이 좋다.
자식 클래스의 객체를 생성하면 자식의 멤버와 부모의 멤버가 합쳐진 하나의 객체가 생성되며. 아래와 같은 순서로 진행된다.
1. 부모클래스의 객체 생성
2. 부모클래스의 생성자 호출
3. 자식 클래스의 객체 생성
4. 자식클래스의 생성자 호출
class Person {
//부모 기본생성자
public Person() {
System.out.println("나는 부모클래스 기본생성자 입니다.");
}
}
class Student extends Person{
//자식 기본생성자
public Student() {
super();
System.out.println("나는 자식클래스 기본생성자 입니다.");
}
}
public class Test {
public static void main(String[] args) {
Student st = new Student();
//출력결과
//나는 부모클래스 기본생성자 입니다.
//나는 자식클래스 기본생성자 입니다.
}
}
6. 메서드 오버 라이딩
메서드 오버 라이딩은 부모 클래스에서 상속받은 메서드를 자식 클래스에서 재정의 하는 걸 말하며 메서드명, 매개변수 타입, 개수, 순서가 동일해야 한다. (단, private는 제외)
자식클래스 객체를 선언한 후 오버 라이딩 한 print() 메서드를 호출하면 재정의한 자식의 메서드 print()가 출력된다. 만약 재정의 하지 않았다면 부모의 print() 메서드가 호출되었을 것이다.
class Person {
void print() {
System.out.println("난 부모야");
}
}
class Student extends Person{
@Override
void print() {
System.out.println("난 자식이야");
}
}
public class Test {
public static void main(String[] args) {
Student st = new Student();
st.print(); // 출력=> 난 자식이야
}
}
7. Object Class (오브젝트 클래스)
자바의 모든 클래스는 최상위 클래스인 Object클래스를 상속받는다.
즉, 자바의 모든 클래스는 별도로 extends 키워드를 사용하지 않아도 Object의 클래스의 모든 멤버를 사용할 수 있다. 자바의 모든 객체에서 toString()이나 clone()과 같은 메서드를 바로 사용할 수 있는 이유가 해당 메서드들이 Objcet 클래스의 메서드이기 때문이다.
📌Reference
http://www.tcpschool.com/java/java_inheritance_concept
해당 글은 학습한 내용을 개인적으로 정리한 글입니다. 만약 틀린 부분이 있다면 댓글로 남겨주세요:D