상속
상속이란
- 상속이란 기존 클래스를 재사용하여 새로운 클래스를 작성하는 자바의 문법 요소로 상위 클래스의 멤버를 내려받아 하위 클래스 내부에 포함시키는 역할을 한다.
- 여기서 기존 클래스는 상위(부모) 클래스, 새로운 클래스는 하위(자식) 클래스라고 한다.
- 상위 클래스와 하위 클래스는 서로 상속 관계라고 하며, 하위 클래스는 상위 클래스가 가진 모든 멤버를 상속받는다.
- '하위 클래스는 상위 클래스로부터 확장되었다'라고 표현한다.
- 상속 관계로 정의하기 위해서는 '하위 클래스는 상위 클래스다' 라는 조건이 참이어야 한다.
-> ex. '고양이는 동물이다.'(상속 가능) / '취준생은 학생이다.' (상속 불가능)
상속의 장점
- 코드의 중복성 제거
- 클래스의 다형적 표현 가능
- 다형성 : 1개의 객체를 여러 가지로 표현할 수 있는 특성
ex. '프로그래머는 프로그래머다.' / '프로그래머는 사람이다.'
상속 정의
- 클래스를 상속할 때는 'extends' 키워드를 사용한다.
- 상위 클래스가 2개 이상인 다중 상속은 할 수 없다.
-> 2개의 상위 클래스 중에서 이름이 같은 멤버가 존재할 경우 모호성이 발생하기 때문에
// 상속
class 하위 클래스 extends 상위 클래스 {
}
// 다중 상속 불가
class 하위 클래스 extends 상위 클래스1, 상위 클래스 2 { // 불가
}
// 다중 상속 불가 예시
class A {
int age = 20;
}
class B {
int age = 30;
}
class C extends A, B {
// age = 상위 클래스로부터 어떤 값을 상속?
}
상속 메모리 구조
class 상위 클래스 {
}
class 하위 클래스 extends 상위 클래스{
}
// 하위 클래스 생성자로 인스턴스 생성
하위 클래스 참조 변수 = new 하위클래스();
- 하위 클래스는 상위 클래스를 상속받았기 때문에 하위 클래스 인스턴스 내부에 상위 클래스의 인스턴스가 존재
-> 하위 클래스 인스턴스로 상위 클래스의 멤버를 사용할 수 있어야 하기 때문에 자바 가상 머신은 하위 클래스의 인스턴스를 생성할 때 가장 먼저 상위 클래스의 인스턴스를 생성 - 참조 변수는 하위 클래스의 자료형으로 선언됐기 때문에 하위 클래스 인스턴스의 주소값을 참조
상위 클래스 자료형으로 하위 클래스 인스턴스를 생성 시 상위 클래스 인스턴스의 주소값을 참조
상속 예시
public class Main {
public static void main(String[] args) {
Person person = new Person("백두산", 24);
Programmer programmer = new Programmer("한라산", 23, "구글");
Dancer dancer = new Dancer("설악산", 29, "유명한 댄스 그룹");
// Person에서 확장되었기 때문에 Person 자료형으로 생성 가능 (다형성)
Singer singer = new Singer("금강산", 21, "유명한 밴드 그룹");
person.learn("코딩");
dancer.dancing();
singer.singing();
person.eat("회");
// Dancer 클래스 내부에 따로 메서드를 작성하지 않았는데도 호출 가능 -> 상속
dancer.eat("야채");
singer.eat("도라지");
}
}
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void learn(String something) {
System.out.println(name + "이(가) " + something + "을 배웁니다.");
}
public void walk() {
System.out.println(name + "이(가) 을 걷습니다.");
}
public void eat(String food) {
System.out.println(name + "이(가) " + food + "을(를) 먹습니다.");
}
}
// 상속 X -> 동일한 기능을 하는 learn, walk, eat을 새로 작성해야 함.
class Programmer {
private String name;
private int age;
private String companyName;
public Programmer(String name, int age, String companyName) {
this.name = name;
this.age = age;
this.companyName = companyName;
}
public void learn(String something) {
System.out.println(name + "이(가) " + something + "을 배웁니다.");
}
public void walk() {
System.out.println(name + "이(가) 을 걷습니다.");
}
public void eat(String food) {
System.out.println(name + "이(가) " + food + "을(를) 먹습니다.");
}
public void coding() {
System.out.println(name + "이(가) 코딩을 합니다.");
}
}
// Person 상속 -> Person의 멤버 재사용 가능
class Dancer extends Person {
String groupName;
public Dancer(String name, int age, String groupName) {
super(name, age);
this.groupName = groupName;
}
public void dancing() {
System.out.println(groupName + "의" + name + "이(가) 춤을 춥니다.");
}
}
// Person 상속 -> Person의 멤버 재사용 가능
class Singer extends Person {
String bandName;
public Singer(String name, int age, String bandName) {
super(name, age);
this.bandName = bandName;
}
public void singing() {
System.out.println(bandName + "의" + name + "이(가) 노래를 합니다.");
}
}
포함 관계
포함 관계란
포함(composite)은 상속처럼 클래스를 재사용할 수 있는 방법으로, 클래스의 멤버로 다른 클래스 자료형의 참조 변수를 선언하는 것을 의미한다.
예시
- Person 클래스가 가지는 이름, 주소, 주민번호를 IdCard 클래스를 정의해 해당 정보를 묶어줌.
- Person은 3개의 변수대신 IdCard 자료형의 참조 변수를 선언하여 코드의 중복을 없애고 포함관계로 재사용
public class Main {
public static void main(String[] args) {
IdCard idCard1 = new IdCard("홍길동", "111111-111111", "포항시 xxx-xxx");
Person person1 = new Person(idCard1, "남자");
person1.sleep();
System.out.println("제 이름은 " + person1.idCard.name + "입니다.");
}
}
class IdCard {
final String name;
final String idNumber;
final String address;
public IdCard(String name, String idNumber, String address) {
this.name = name;
this.idNumber = idNumber;
this.address = address;
}
}
class Person {
IdCard idCard;
String gender;
public Person(IdCard idCard, String gender) {
this.idCard = idCard;
this.gender = gender;
}
public void sleep() {
System.out.println(idCard.name +"(이)가 잠을 잡니다.");
}
}
상속 관계와 포함 관계 구분
- 클래스 간의 관계가 '~은 ~이다.(IS-A)' 관계인지 '~은 ~을 가지고 있다(HAS-A)' 관계인지 생각해보기.
- ~은 ~이다.(IS-A) : 상속 관계
- Animal - Cat : '고양이는 동물이다.(IS-A)' - O / '동물은 고양이를 가지고 있다.(HAS-A)' - X : 상속 관계
- ~은 ~을 가지고 있다(HAS-A) : 포함 관계
- Person - IdCard : '아이디카드는 사람이다.(IS-A)' - X / '사람은 아이디카드를 가지고 있다.(HAS-A)' - O : 포함 관계
'Langauge > Java-basic' 카테고리의 다른 글
[Java] instanceof : 캐스팅 가능 여부 확인 (0) | 2022.07.30 |
---|---|
[Java] 업 캐스팅과 다운 캐스팅 (0) | 2022.07.30 |
[Java] final 키워드 (0) | 2022.07.25 |
[Java] static 키워드 (0) | 2022.07.24 |
[Java] 접근 제어자 public / protected / default / private (0) | 2022.07.23 |