안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
상속이란?
- 부모 클래스의 멤버(필드, 메소드, 이너클래스)를 내려받아 자식 클래스 내부에 포함
부모 클래스는 자식 클래스의 공통적 특징을 모아 구성한 클래스
상속의 장점
① 코드의 중복성 제거
② 다형적 표현 가능
상속 문법
class 자식 클래스 extends 부모 클래스 {
//...
}
단, 자바의 클래스는 다중 상속이 불가!!! (부모 클래스가 2개 이상일 때를 의미)
그 이유는, 만일 class A와 B 모두 data라는 필드를 포함하고 있을 때 class C가 상속을 하면 C 또한 data 필드를 갖고 있을 것입니다.
그럴 때 A의 data 값이 3이고, B의 data 값이 4일 때, C는 A클래스 값이 적용되면 3이 적용될 것이고 B클래스 값이 적용되면 4가 적용 될 것입니다.
이렇듯 다중 상속을 허용하게 된다면, 모호성이 발생하기 때문에 자바는 다중 상속이 불가합니다.
//부모 클래스
class Parent {
String name;
int age;
public void say() {
System.out.println("부모클래스");
}
public String information() {
return "name = " + name + ", age = " + age;
}
}
//자식클래스
class Child extends Parent {
}
부모 클래스인 Parent에 name, age 필드와 say(), information() 메소드를 정의하고 Parent 클래스를 상속 받은 Child 클래스를 정의하였습니다.
public class InheritanceBasicMain {
public static void main(String[] args) {
Child child = new Child();
child.name = "자식클래스";
child.age = 15;
child.say();
System.out.println(child.information());
}
}
@콘솔출력값
부모클래스
name = 자식클래스, age = 15
Child 객체를 생성한 후 name, age필드에 값을 대입하고 say() 메소드, information() 메소드를 출력하였습니다.
Child 클래스 내부에는 아무런 코드가 정의되지 않았었는데, 부모 클래스로부터 물려받은 name, age필드를 가져와 값 대입을 할 수 있었으며 say() 메소드와 information메소드 또한 출력이 가능했습니다.
즉 Child 클래스에도 부모 클래스 내부에 있는 필드, 메소드가 보이진 않지만 정의가 되어있는 것이죠.
그렇다면, 부모 클래스는 단 하나의 자식 클래스만 상속할 수 있을까요?
아닙니다. 위에서 말한 다중 상속은 부모 클래스가 2개 이상이 불가한 것이고, 자식 클래스는 100개 1,000개든 상관없습니다.
//부모클래스
class Parent {
String name;
int age;
public void say() {
System.out.println("부모클래스");
}
public String information() {
return "name = " + name + ", age = " + age;
}
}
//Parent 자식 클래스1
class Child extends Parent {
}
//Parent 자식 클래스1
class OtherChild extends Parent {
}
Child 클래스와 OtherChild 클래스 모두 Parent 클래스를 상속하고 있으며, 위와 같은 상속 구조를 띄고 있습니다.
public class InheritanceBasicMain {
public static void main(String[] args) {
// Child child = new Child();
// child.name = "자식클래스";
// child.age = 15;
// child.say();
// System.out.println(child.information());
OtherChild otherChild = new OtherChild();
otherChild.name = "엄친아";
otherChild.age = 20;
otherChild.say();
System.out.println(otherChild.information());
}
}
@콘솔출력값
부모클래스
name = 엄친아, age = 20
마찬가지로 OtherChild 객체 생성 후 각 필드에 값 대입, 메소드 출력을 해보았습니다.
부모 클래스의 필드, 메소드를 상속 받아 사용한 것을 알 수 있습니다.
상속 받은 자식 클래스는 반드시 부모 클래스의 멤버만 사용해야할까요?
아닙니다. 자식 클래스에서도 필요한 멤버들을 추가할 수 있습니다.
Child 클래스에 필드, 메소드를 추가해보았습니다.
class Parent {
String name;
int age;
public void say() {
System.out.println("부모클래스");
}
public String information() {
return "name = " + name + ", age = " + age;
}
}
class Child extends Parent {
String game = "LOL";
public void doGame() {
System.out.println(name + "가 " + game + "게임을 한다.");
}
}
이렇게 되면, Child클래스에서 사용할 수 있는 필드는 상속 받은 부모 클래스의 name, age와 Child클래스의 game필드
사용할 수 있는 메소드는 상속 받은 부모 클래스의 say(), information()과 Child클래스의 doGame()메소드가 됩니다.
public class InheritanceBasicMain {
public static void main(String[] args) {
Child child = new Child();
child.name = "자식클래스";
child.age = 15;
child.say();
System.out.println(child.information());
child.doGame();
}
}
@콘솔출력값
부모클래스
name = 자식클래스, age = 15
자식클래스가 LOL게임을 한다.
자바에서는 다중 상속이 불가하다고 했습니다.
그렇다면 부모 클래스 + 자식 클래스의 멤버들을 사용하고 싶을 땐 어떻게 해야할까요?
자식 클래스를 상속하면 됩니다!
class Parent {
String name;
int age;
public void say() {
System.out.println("부모클래스");
}
public String information() {
return "name = " + name + ", age = " + age;
}
}
class Child extends Parent {
String game = "LOL";
public void doGame() {
System.out.println(name + "가 " + game + "게임을 한다.");
}
}
class GrandChild extends Child {
}
Child가 Parent를 상속하고 GrandChild가 Child를 상속하고 있습니다.
그렇다면 GrandChild에서 사용할 수 있는 멤버는 어떻게 될까요?
Parent의 name, age필드 + say(), information()메소드 / Child의 game 필드 + doGame()메소드가 됩니다.
그 이유는 Child에서 상속 받은 부모 클래스의 멤버들을 사용할 수 있으므로 부모 클래스의 멤버들을 포함하고 있다고 하였습니다.
따라서 Child를 상속하는 GrandChild 또한 Child의 멤버들을 사용할 수 있으므로 이처럼 사용이 가능한 것이죠.
public class InheritanceBasicMain {
public static void main(String[] args) {
GrandChild grandChild = new GrandChild();
grandChild.name = "손자";
grandChild.age = 3;
grandChild.say();
System.out.println(grandChild.information());
grandChild.doGame();
}
}
@콘솔출력값
부모클래스
name = 손자, age = 3
손자가 LOL게임을 한다.
이러한 상속 구조를 띄고 있습니다.
그렇다면, 어떻게 부모 클래스의 멤버들을 사용할 수 있는 것일까요?
메모리 구조를 확인해보겠습니다.
클래스 영역(static영역)에는 선언된 자료형의 클래스와 부모 클래스가 모두 로딩됩니다.(그림은 생략)
이 때 참조변수 child는 Child 자료형으로 선언됐기 때문에 힙 메모리에 있는 Child 타입 객체만을 가리킬 수 있습니다.
JVM은 자식 클래스의 객체를 생성할 때 가장 먼저 부모 클래스의 객체를 생성합니다.
그 이후, 자식 클래스에서 추가한 필드와 메소드가 객체에 추가됨으로써 child 클래스의 전체 객체가 완성됩니다.
따라서 자식 클래스 객체의 내부에는 부모 클래스 객체가 포함돼있으므로 자식 클래스 객체에서 부모 클래스의 멤버를 사용할 수 있는 것입니다.
Do it! 자바 완전 정복을 참고하여 포스팅하였습니다.
'Java > Java' 카테고리의 다른 글
상속) 최상위 클래스 Object, toString(), equals(Object obj), hashCode(), clone() (0) | 2022.03.21 |
---|---|
상속) 상속의 특징, 생성자 상속 여부 (0) | 2022.03.21 |
배열) 객체 배열, VO class 설계 (0) | 2022.03.18 |
this키워드(this.)와 this()메소드 (0) | 2022.03.17 |
생성자) 기본 생성자, 파라미터 생성자, 생성자 오버로딩, this() (0) | 2022.03.17 |