안녕하세요, 스코리아입니다.
오늘은 자바 객체 간의 상속의 의미와 구현 방법을 예시와 함께 알아보겠습니다.
클래스 상속 (Class Inheritance) 의미
- 새로운 클래스를 정의할 때 이미 구현된 클래스를 상속받아서 속성이나 기능을 확장하여 클래스를 구현함
- 이미 구현된 클래스보다 더 구체적인 기능을 가진 클래스를 구현해야 할 때 기존 클래스를 상속함
- 상속하는 클래스: 상위 클래스, parent class, base class, super class
- 상속받는 클래스: 하위 클래스, child class, derived class, sub class
상속 문법 (방법)
class B extends A {
}
상속을 구현하는 경우
- 상위 클래스는 하위 클래스보다 더 일반적인 개념, 기능을 가짐
- 하위 클래스는 상위 클래스보다 더 구체적인 개념, 기능을 가짐
- 하위 클래스가 상위 클래스의 속성, 기능을 확장(extends)한다는 의미
class Mammal{
}
class Human extends Mammal{
}
- 예시처럼 포유류 안에 사람이 있으므로 사람은 하위 클래스, 포유류는 상위 클래스라고 할 수 있음
- 사람(하위 클래스)이 더 구체적인 개념을 갖고 포유류(상위 클래스)가 더 일반적인 개념을 가짐
- 사람(하위 클래스)가 포유류(상위 클래스)의 속성, 기능을 더 확장함
상속을 활용한 예시
- 회사에서 일반고객(Customer)과 우수고객(VIPCustomer)에 따른 서비스를 제공하고자 함
- 등급에 따라 고객이 물품을 구매할 때 적용되는 할인률과 적립되는 보너스 포인트의 비율이 다름
- 물품 구매 시일반고객은 1% 보너스 포인트 적립, 우수고객은 5% 보너스 포인트 적립
- 물품 구매 시 일반고객은 할인 없음, 우수고객은 10% 할인
- 일반 고객은 Silver 등급을, 우수고객은 VIP 등급을 부여
- 이런 멤버십에 대한 구현을 클래스 상속을 활용해 구현해 보기
우선 일반고객 클래스를 구현하기 위해 Customer.java 파일을 만들어보겠습니다.
public class Customer {
protected int customerID;
protected String customerName; // protected : 외부 클래스는 접근 할 수 없지만, 같은 패키지내 하위 클래스는 접근 할 수 있도록함
protected String customerGrade; // 등급
protected int bonusPoint; // 보너스 포인트
protected double bonusRatio; // 보너스 적립 비율
// 기본 생성자가 아닌 매개 변수가 있는 생성자
public Customer(int customerID, String customerName, int bonusPoint) {
System.out.println("Customer() 생성자 호출");
this.customerID = customerID;
this.customerName = customerName;
this.bonusPoint = bonusPoint;
customerGrade = "SILVER";
bonusRatio = 0.01;
}
public String showCustomerInfo() {
return customerName + "님의 등급은 " + customerGrade + "이며, 보너스 포인트는" + bonusPoint + "입니다";
}
}
- 멤버 변수로 고객 아이디(customerId), 고객 이름(customerName), 고객 등급(customerGrade), 보너스 포인트(bonusPoint), 보너스 포인트 적립 비율(bonusRatio)을 만들어 주었습니다.
- 고객 아이디, 이름, 보너스 포인트를 매개 변수로 받는 Customer() 생성자를 만들고, 1%의 보너스 포인트 적립을 위해 bonusRatio를 0.01로 설정, customerGrade는 SILVER로 설정하였습니다.
- 고객의 정보를 출력하는 showCustomerInfo() 메소드를 만들어 주었습니다.
- 여기서 멤버 변수들을 모두 protected 접근 제어자로 설정함으로써, 외부 클래스는 접근 불가능하지만 같은 클래스 내 하위 클래스는 접근 가능하게끔 하였습니다.
- 상위 클래스(Customer.class) 멤버변수에 private 접근 제어자를 사용하게 되면, 하위 클래스에서는 접근이 불가하고 같은 클래스 내에서만 접근이 가능합니다.
이제 하위 클래스인 우수 고객 클래스를 구현하기 위해 VIPCustomer.java 파일을 만들어보겠습니다.
// VIPCustomer는 이미 Customer에 구현된 내용과 중복되므로 Customer를 확장하여 구현함 (상속)
public class VIPCustomer extends Customer{
private int agentId;
private double salesRatio;
public VIPCustomer(int customerID, String customerName, int bonusPoint) {
super(customerID, customerName, bonusPoint); // super를 이용하여 상위 클래스의 생성자 명시적 호출
System.out.println("VIPCustomer() 생성자 호출");
customerGrade = "VIP";
bonusRatio = 0.05;
salesRatio = 0.1;
}
}
- Customer에 구현된 내용을 VIPCustomer도 똑같이 사용할 필요가 있습니다.
- 즉, VIPCustomer는 이미 Customer에 구현된 내용이 중복되므로 Customer를 확장(extends)하여 구현합니다.
- 'extends' 키워드를 사용하여 Customer를 상속받을 것을 암시했습니다.
- 멤버 변수로 담당 전문 상담원(agentId)과 할인률(salesRatio)을 만들어주었습니다.
- 위 그림과 같이 상속 관계를 표현할 수 있습니다.
- 나중에 VIP Customer뿐만 아니라 Gold Customer, Platinum Customer 등을 추가할 수 있습니다.
super 키워드
- 하위 클래스에서 가지는 상위 클래스에 대한 참조 값
- super()는 상위 클래스의 기본 생성자를 호출함
- 상위 클래스의 기본 생성자가 존재하는 경우: 하위 클래스 생성자에서 명시적으로 super() 호출을 하지 않으면, 자동으로 super()가 호출됨
- 상위 클래스의 기본 생성자가 존재하지 않는 경우 (다른 생성자 존재): 하위 클래스 생성자에서 super() 호출을 통해 명시적으로 상위 클래스의 생성자를 호출해야 함
- super는 생성된 상위 클래스의 인스턴스 참조 값을 가지므로 super를 이용하여 상위 클래스의 메소드나 멤버변수에 접근할 수 있음 (위의 예시를 보면, bonusRatio가 아닌 super.bonusRatio라고 적을 수 있음)
- 상위 클래스인 Customer에서 customerGrade를 private로 설정했다면 하위 클래스인 VIPCustomer의 생성자에서는 customerGrade 변수 접근이 불가능했을 것입니다. 그러므로 protected 접근자로 설정해 준 것입니다.
이제 Customer, VIPCustomer 인스턴스를 만들어 테스트해 보기 위해 CustomerTest.java 파일을 만들어보겠습니다.
public class CustomerTest {
public static void main(String[] args) {
Customer customerLee = new Customer(10010, "손흥민", 1000);
System.out.println(customerLee.showCustomerInfo());
VIPCustomer customerKim = new VIPCustomer(10020, "김민재", 10000);
System.out.println(customerKim.showCustomerInfo());
}
}
- "손흥민" 이름을 가진 Customer 인스턴스를 생성 후, showCustomerInfo 메소드를 호출하였습니다.
- "김민재" 이름을 가진 VIPCustomer 인스턴스를 생성 후, showCustomerInfo 메소드를 호출하였습니다.
- VIPCustomer 파일 자체에는 showCustomerInfo 메소드가 없지만, VIPCustomer는 Customer를 상속받고 있기 때문에 상위 클래스 메소드 호출이 가능합니다.
- Customer 생성자가 처음에 호출되었습니다.
- Customer의 showCustomerInfo 메소드가 호출되어 "손흥민" 고객님의 정보가 출력되었습니다.
- VIPCustomer 생성자를 호출하면, super() 키워드 때문에 상위 클래스인 Customer 클래스의 생성자가 먼저 호출되었습니다.
- 그 후, VIPCustomer 생성자가 호출되었습니다.
- VIPCustomer(Customer)의 showCustomerInfo 메소드가 호출되어 "김민재" 고객님의 정보가 출력되었습니다.
- Customer, VIPCustomer에 매개 변수가 있는 생성자가 아닌 기본 생성자만 존재하고, VIPCustomer 생성자에 super 키워드를 생략한다면, 하위 클래스를 생성하면 이때도 마찬가지로 상위 클래스가 먼저 생성됩니다.
- 즉, 이 상황에서 new VIPCustomer()를 호출하면 Customer()가 먼저 호출됩니다.
- 클래스가 상속받은 경우 하위 클래스의 생성자는 반드시 상위 클래스의 생성자를 우선적으로 호출합니다.
지금까지 자바(Java)의 객체 간의 상속 의미, 구현방법, 예시에 대해서 알아보았습니다.
읽어주셔서, 감사합니다.
'JAVA > 객체지향' 카테고리의 다른 글
자바 메소드 재정의 의미, 사용방법 (@Override) (2) | 2023.08.31 |
---|---|
자바 자동타입변환(업케스팅 형변환) 의미, 사용 방법 (2) | 2023.08.29 |
자바 싱글톤 패턴 의미, static 활용한 구현 (singleton pattern) (2) | 2023.08.18 |
자바 static 변수 뜻, 의미, 사용방법 그리고 유효범위 (3) | 2023.08.17 |
자바 this / this() 뜻, 의미, 사용방법에 대해서 (1) | 2023.08.15 |