상속이란 우리 인간들의 세계에서 사용하는 그 상속과 동일한 개념이다.
프로그래밍에서 상속을 사용하는 가장 큰 이유는 바로 재사용성을 높이기 위해서이다. 부모 클래스로부터 상속을 받은 기능은 또 새로 정의할 필요 없이 사용만 하면 되기 때문이다.
상속(Inheritanc)의 원칙
- 부모 클래스에 새로운 기능이나 속성을 추가하여 새로운 자식 클래스로 만드는 것을 의미한다.
- 상속개념을 적용함으로써 개발시간 단축, 재사용성 등으로 OOP 장점을 살릴 수 있다.
- 상속관계는 부모와 자식간에 "자식 is a부모"라는 'is a'관계가 성립할 때 맺을 수 있다.
- Java에서 상속을 받을 때는 extends란 키워드를 사용한다.
- Java는 단일 상속 개념이므로 extends로 상속 받을 수 있는 클래스는 단 하나뿐이다.
- private 접근지정자가 붙은 부모의 맴버는 상속은 받으나 접근 불가하다.
<상속의 형식>
이제부터 예제를 통해서 상속을 알아가보자.
우선 사람을 추상화(클래스화)해보자.
▲ 사람의 특성과 행동을 변수와 메소드로 만들었다.
여기서 주목할 점은 Person이라는 클래스처럼 아무에게도 상속 받지 않는 모든 클래스는 최상위 클래스인 Object에게 Object의 맴버들을 상속 받는다.
또한 위 코드에서 super() 라는 기본생성자에서 super는 해당 생성자가 속해있는 클래스의 부모클래스의 기본생성자를 뜻한다.
이제 우리가 클래스화 한 사람을 학생과 선생님이라는 객체를 추상화할 때 사용해보도록 하자.
우선 학생부터 추상화(클래스화)해보자.
▲ 여기서 Student뒤에 extends Person이 붙어 있는 것으로 보아 Student는 Person을 상속받은 것을 알 수 있다.
상속의 원칙에서도 봤다시피 상속에서는 is a 관계가 성립해야 한다. Person is a Student는 성립하지 않는다. 왜냐하면 모든 사람이 학생은 아니기 때문이다. Student is a Person은 성립한다. 모든 학생은 사람이기 때문이다.
학생도 이름과 나이 사는 곳은 존재하지만 우리는 Person을 상속받았으므로 Person에 있는 맴버변수인 name, age, addr를 상속받아 그냥 사용할 것이다. 이것이 재사용한다고 하는 것이다. 거기에 우리는 학생만이 가지고 있는 학번이라는 맴버변수를 추가해 확장하여 진정한 상속을 할 것이다.
기본생성자에 있는 super()에서 super는 해당 super가 속해있는 클래스의 부모 클래스를 가리킨다고 했다.
Student클래스의 부모 클래스는 Object가 아닌 Person이므로 super()는 Person클래스의 기본생성자를 의미하는 것이다. 기본생성자는 인자생성자가 없으면 자동으로 제공되기 때문에 위 코드에서는 없어도상관없다.
▲ Student클래스의 인자생성자를 만들고 Person클래스에 있던 메소드들은 역시 재사용을 할 것이므로 새로 만들지 않고 학생만이 가지고 있는 활동들을 메소드로 만들자. 이를 통해 메소드 또한 확장시켜 진정한 의미의 상속을 실현했다.
이번에는 선생님를 추상화하자.
▲Student와 마찬가지로 Person의 상속을 받음으로써 중복되는 맴버들은 상속받은 것을 재사용하고 선생님이 가지고 있는 고유의 속성과 활동을 추가해 확장시켜보자.
▲ 선생님만이 가진 고유한 행동과 출력용 메소드를 만들었다.
이제 우리가 만든 클래스들로 출력을 해보자.
▲ 메인메소드에서 호출해보자. student1 = new Student()를 하는 순간 즉, 기본생성자를 호출하는 순간 Student의 기본생성가 호출되어 실행된다.
Student의 기본생성자에서 첫번째줄에는 생략되어 있는 super() 즉, 부모클래싀의 기본생성자를 호출하게 되고 부모클래스인 Person의 기본생성자(Person( ))를 호출하여 실행하게 된다. PErson()에도 Object기본생성자를 가리키는 super()가 있지만 아무것도 하는 일이 없기 때문에 출력되는 것은 없으며 그 다음코드인 "Person의 기본생성자"가 출력된다.
이후 Person()은 끝이 났으므로 호출한 곳(Student( ))로 돌아오게 되고 "Student의 기본생성자"가 출력된다.
student1.printStudent()를 실행해도 값이 모든 값이 null과 0으로 출력되는 것은 우리가 따로 초기화 하지 않았기 때문이다.
이번에는 우리가 값을 초기화하고 출력해보자.
▲ 우리가 값을 초기화 하면 초기화를 한 값으로 원하는 형식으로 잘 출력된다.
▲ Student의 기본생성자가 아닌 인자생성자로 인자값을 받아 매개변수로 전달 후 초기화할 수도 있다.
▲ Person의 기본생성자 -> Student의 인자생성자 순으로 sysout이 출력되는 이유는 위 노란색으로 강조해서 설명한 부분과 같은 순서와 방법으로 접근되었기 때문이다.
선생님 또한 마찬가지의 방법과 순서이다. Student와 같은 부모로부터 상속을 받았기 때문이다.
▲ 위 코드에서 new Teacher()가 안되는 이유는 우리가 Teacher.java 파일에서 생성자를 정의할 때 기본생성자는 정의하지 않고 인자생성자만 정의했기 때문이다.
기본생성자는 말그대로 기본으로 java에서 제공하지만 우리가 인자생성자를 하나라도 만드는 순간 필요없다고 판단하여 제공해주지 않기 때문이다. 따라서 우리가 다른 클래스에서 기본생성자를 사용하기 위해서는 해당 클래스(여기서는 Teacher)에서 기본생성자를 직접 만들어줘야한다.
우리는 Teacher() 기본생성자를 사용하지 않고 인자생성자만 사용할 것이기 때문에 굳이 만들지 않겠다.
'Java' 카테고리의 다른 글
[Java]오버라이드(Override) (0) | 2022.03.15 |
---|---|
[Java]Super() - 부모의 기본생성자 (0) | 2022.03.14 |
[Java]String Constructor (0) | 2022.03.14 |
[Java]싱글톤 디자인(Single Tone Design) (0) | 2022.03.14 |
[Java]this() - 자기 자신의 기본생성자 (0) | 2022.03.14 |