- 상속이란
상속: 물려주다
A 클래스가 B 클래스에게 상속한다
= B 클래스가 A 클래스를 상속받는다
이때 A 클래스가 상위 클래스, B 클래스가 하위 클래스가 된다.
- 구현
상속은 extends 예약어를 통해 구현한다.
class B extends A {
}
- 상속의 기능
상위 클래스에서 작성한 변수나 메서드를 사용할 수 있다.
이때 상위 클래스의 변수나 메서드 중 외부 클래스에서는 사용할 수 없지만 하위 클래스에서는 사용할 수 있도록 지정하는 것이 protected 예약어
- 하위 클래스가 상위 클래스의 변수나 메서드를 사용할 수 있는 이유
하위 클래스가 생성 될때 상위 클래스의 생성자가 먼저 호출되고 그 다음에 하위 클래스의 생성자가 호출되기 때문.
즉, 상위 클래스의 변수가 메모리에 먼저 생성되기 때문에 하위 클래스에서 이들을 사용할 수 있는 것
- 예시
Customer와 VIPCustomer
package first_project;
public class Customer {
protected int customerId;
protected String customerName;
protected String customerGrade;
int bonusPoint;
double bonusRatio;
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerGrade() {
return customerGrade;
}
public void setCustomerGrade(String customerGrade) {
this.customerGrade = customerGrade;
}
public Customer() {
System.out.println("Customer 생성자 호출됨");
customerGrade = "Silver";
bonusRatio = 0.01;
}
public int calcPrice(int price) {
bonusPoint += price* bonusRatio;
return price;
}
public String showCustomerInfo() {
return customerName+ "님의 등급은 "+customerGrade+"이며, 보너스 포인트는 "+bonusPoint+"입니다.";
}
}
package first_project;
public class VIPCustomer extends Customer {
private int agentId;
double saleRatio;
public VIPCustomer() {
System.out.println("VIPCustomer 생성자 호출됨");
customerGrade = "VIP";
bonusRatio = 0.05;
saleRatio = 0.1;
}
public int calcPrice(int price) {
bonusPoint += price* bonusRatio;
return price - (int)(price* saleRatio);
}
public int getAgentId() {
return agentId;
}
}
package first_project;
public class CustomerTest {
public static void main(String[] args) {
Customer customerLee = new Customer();
customerLee.setCustomerId(1010);
customerLee.setCustomerName("이순신");
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());
VIPCustomer customerKim = new VIPCustomer();
customerKim.setCustomerId(2020);
customerKim.setCustomerName("김유신");
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
}
}
결과
Customer 생성자 호출됨
이순신님의 등급은 Silver이며, 보너스 포인트는 1000입니다.
Customer 생성자 호출됨
VIPCustomer 생성자 호출됨
김유신님의 등급은 VIP이며, 보너스 포인트는 10000입니다.
- 그렇다면 왜 상위 클래스의 생성자가 먼저 호출될까?
하위 클래스 생성자에서 super()를 자동으로 호출하기 때문. super()를 호출하면 상위 클래스의 디폴트 생성자가 호출됨.
* 예약어 super
super는 하위 클래스에서 상위 클래스로 접근할 때 사용
상위 클래스의 생성자를 호출할 때도 사용
- super()는 상위 클래스의 디폴트 생성자를 호출한다고 했는데, 매개변수가 있는 생성자를 호출하고 싶다면?
Customer의 디폴트 생성자를 없애고 아래와 같이 생성자를 새로 작성해보자. (매개변수가 있는 형태)
public Customer(int customerId, String customerName) {
this.customerId = customerId;
this.customerName = customerName;
customerGrade = "Silver";
bonusRatio = 0.01;
System.out.println("Customer(int, String) 생성자 호출됨");
}
그러면 하위 클래스의 생성자에서 오류가 나게됨. super()를 호출해야 되는데 super()가 없기 때문.
즉 디폴트 생성자 Customer()가 정의되지 않았기 때문에 명시적으로 다른 생성자를 호출해야 한다는 뜻임
따라서 VIPCustomer의 생성자에서도 명시적으로 상위클래스의 생성자를 호출하면 된다.
public VIPCustomer(int customerId, String customerName, int agentId) {
super(customerId, customerName);
customerGrade = "VIP";
bonusRatio = 0.05;
saleRatio = 0.1;
this.agentId = agentId;
System.out.println("VIPCustomer(int, String) 생성자 호출됨");
}
테스트
package first_project;
public class CustomerTest {
public static void main(String[] args) {
VIPCustomer customerKim = new VIPCustomer(2020, "김유신", 111);
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
}
}
결과
Customer(int, String) 생성자 호출됨
VIPCustomer(int, String) 생성자 호출됨
김유신님의 등급은 VIP이며, 보너스 포인트는 10000입니다.
댓글