Code.presso Java 웹 개발 트랙 체험단 활동 2주차 두번째 코스로, 지난 시간에 이어 오늘은 상속과 다형성에 대해 학습한 내용을 정리해보려고 한다!
강의 제목은 "Java Programming 초급" 으로, 자세한 정보는 👇🏻아래👇🏻 링크를 통해 확인할 수 있다.
✋🏻 포스팅 내 사용된 사진 파일들의 저작권은 모두 코드프레소에 있으며, 강의자료 공유 및 업로드는 불가능합니다.
상속이란, 일반화된 특성이 정의된 클래스가 있다고 가정했을 때 그 일반화된 특성을 모두 가지면서 specific한 특성까지 모두 가지는 것을 의미한다.
쉽게 말해서, 일반화된 클래스(부모 클래스)를 재사용하여 새로운 specific한 클래스(자식 클래스)를 생성하는 것이다.
자식 클래스는 부모 클래스의 모든 멤버변수와 메소드를 상속받으며, 상속의 횟수는 제한이 없다.
상속은 객체지향 프로그래밍을 구성하는 주요 특징 중 하나인 만큼 매우 중요하며, 클래스 간의 계층적 분류가 가능해진다.
이러한 상속관계에서 상속을 하는 클래스를 부모/상위/기반 클래스라고 부르고,
상속을 받는 클래스를 자식/하위/파생라고 부른다.
Java 에서는 extends
키워드를 사용하여 부모 클래스의 멤버를 상속받아 확장시킬 수 있다.
➡️ class [자식 클래스명] extends [부모 클래스명] {...}
1. 특징
2. 장점
💡 자바는 다중상속을 허용하지 않는다
지난 시간에 접근 제어자는 외부로부터의 접근을 제한하기 위한 목적의 키워드라고 배웠다!
상속 관계의 접근을 제한하기 위해서도 사용되는데, 크게 public
protected
default
private
4가지가 있다.
는 외부로부터 접근을 제한하기 위한 키워드로, 오직 같은 클래스 내에서만 접근이 가능하다.
이처럼 부모 클래스(User
) 를 상속 받은 자식의 클래스(PaidUser
)에서도 접근이 제한된다.
private
멤버 변수에 대해 외부 접근이 필요한 경우, 부모 클래스에 public getter
, public setter
메소드를 제공함으로써 외부 접근을 허용할 수 있다.
protected
접근 제어자는 외부로부터의 접근을 제한하기 위한 키워드라는 점에서는 private
와 같지만, 상속 받은 자식 클래스에서 접근을 가능하게 한다는 점에서 차이가 있다!
부모 클래스의 멤버 변수를 protected
로 설정하면, 자식 클래스에서 접근이 가능한 것을 확인할 수 있다.
상속 관계의 접근 제어에 대해 정리해보자☺️
자식 클래스에서 접근을 제한하기 위해서는 private
을 사용하자.
자식 클래스에서 접근을 허용하기 위해서는 protected
를 사용하자.
멤버 변수의 특성에 맞는 접근 제어자를 선택하는 것이 중요하다.
상속 관계에서 생성자는 어떻게 동작을 할까🤔❓
이처럼 User
클래스가 있고, 이를 상속받는 EnterpriseUser
, 이를 상속받는 UniversityUSer
가 있다고 가정해보자.
각각의 클래스를 생성하고, 기본 생성자 또한 하나씩 생성한 후 메인 메소드에서 UniversityUser
객체를 생성하게 되면, 어떤 결과가 나올까?
결과는 이와 같이 최상위 부모 클래스의 생성자부터 코드가 실행된다!
여기서 알아야 할 부분은💡
명시적인 부모 생성자의 호출이 없는데 어떻게 이러한 결과가 나올 수 있을까🧐❓
바로 super
키워드에 해답이 있다!
Java 에서 super
키워드는 부모 클래스를 의미한다.
super();
는 부모 클래스의 파라미터 없는 생성자를 호출하는데,
만약 자식 클래스에서 부모 클래스 생성자를 명시적으로 호출하지 않으면 Java 컴파일러는 자식 클래스 생성자의 첫번째 라인에 super();
를 자동으로 삽입한다!
이와 같이 원래는 노란색 코드가 없지만, 부모 클래스의 생성자를 명시적으로 호출하지 않았기 때문에 컴파일러가 super();
를 자동으로 삽입해 이전과 같은 결과가 나왔던 것이다.
그렇다면, 파라미터가 있는 생성자는❓
파라미터가 있는 부모 생성자는 Java 컴파일러가 자동으로 호출하지 않는다.
파라미터가 있는 생성자를 호출할 때는 반드시 명시적인 선언이 필요하다.
📌 부모 클래스의 멤버 변수 또는 메소드 접근 시에도
super
키워드를 사용한다.
메소드 오버라이딩은 부모 클래스로부터 상속받은 메소드를 자식 클래스가 자신만의 특성에 맞게 새롭게 구현하는 것이다.
이와 같이 같은 login()
메소드를 호출해도, 자식 클래스가 자신만의 특성에 맞게 새롭게 구현한 대로 결과가 각각 다르게 나오는 것을 확인할 수 있다.
오버라이딩은 코드의 간결성을 유지하면서 내용을 확장시킬 수 있다는 장점이 있다!
1. 오버라이딩하는 부모 클래스의 메소드와 이름이 같아야 한다.
2. 오버라이딩하는 부모 클래스의 메소드와 파라미터가 같아야 한다.
3. 오버라이딩하는 부모 클래스의 메소드와 리턴타입이 같아야 한다.
다형성의 사전적 정의는 다양한 형태를 가지는 성질이다.
다형성은 객체지향의 주요 특성 중 하나로, 비유하자면 동일한 사물이 때에 따라 서로 다른 기능을 할 수 있는 것이다.
정리하자면❗️ 다형성이란❓
💡 Java 클래스는 사용자 정의 타입(User Defined Type)으로서 자료형으로 사용된다.
User
라는 부모 클래스를 상속받은 자식 클래스 3개가 있다.
각 클래스의 멤버 변수를 초기화하는 생성자를 구현하고, 부모 클래스의 login()
메소드를 각각의 자식 클래스에서 오버라이딩 했다고 가정해보자!
지난 시간과는 코드의 구성이 조금 다르다.
User
타입의 grace
참조 변수 하나를 계속해서 재사용하고 있다.
어떤 결과가 나오게 될까🤔❓
동일한 참조 변수임이에도 객체마다 결과가 다르게 잘 나오는 것을 확인할 수 있다!
여기서 알 수 있는 사실은, 하나의 참조 변수가 어떤 객체를 참조하느냐에 따라 다른 특성을 가진다는 것이다.
📌 다형성의 장점
1. 소프트웨어 요구 사항 변경이나 추가에 대해 유연한 설계가 가능하다.
2. 요구사항이 추가 됐을 때 기존 코드의 변경이 최소화된다.
코드프레소 홈페이지(https://www.codepresso.kr/)에는 오늘 포스팅한 상속과 다형성 관련 강의뿐만 아니라 다양한 강의들이 개설되어 있으니 모두 한번 씩 살펴보고 수강해보면 좋을 것 같다😃