Java
[Java] 상속
k_sangmin
2023. 8. 22. 17:37
클래스 상속
- 새로운 클래스를 정의할 때 이미 구현된 클래스를 상속받아서 속성이나 기능을 확장하여 클래스를 구현함
- 이미 구현된 클래스보다 더 구체적인 기능을 가진 클래스를 구현해야 할 때 기존 클래스를 상속함
상속을 구현하는 경우
- 상위 클래스는 하위 클래스 보다 더 일반적인 개녕과 기능을 가짐
- 하위 클래스는 상위 클래스 보다 더 구체적인 개녕과 기능을 가짐
- 하위 클래스가 상위 클래스의 속성과 기능을 (extends) 한다는 의미
용어정리
- 상속하는 클래스 : 상위 클래스, parent class, super class
- 상속받는 클래스 : 하위 클래스, child class, subclass
상속 활용 예제
일반 고객 클래스 구현
- 고객의 속성 : 고객 아이디, 고객 이름, 고객 등급 보너스 포인트, 포인트 적립비율
- 일반 고객의 경우 물품 구매시 1%의 보너스 포인트 적립
public class Customer {
private int customerId;
private String customerName;
private String customerGrade;
int bonusPoint;
double bonusRatio;
public Customer() {
customerGrade = "SILVER";
bonusRatio = 0.01;
}
public int calcPrice(int price) {
bonusPoint += price *bonusRatio;
return price;
}
public String showCustomerInfo() {
return customerName + "님의 등급은" + customerGrade + "이며,보너스 포인트는 + "
+ bonusPoint + "입니다.";
}
}
골드 고객 클래스 구현
- 매출에 더 많은 기여를 하는 단골 고객
- 보너스 포인트는 제품 가격의 5%를 적립해 줌
- 담당 전문 상담원이 배정됨
- Customer에 구현된 내용과 중복되는 부분은 Customer를 상속하여 구현
public class GoldCustomer extends Customer {
private int agentID;
double salesRatio;
public GoldCustomer() {
customerGrade = "GOLD";
bonusRatio = 0.05;
salesRatio = 0.1;
}
public int getAgentId() {
return agentID;
}
}
접근 제어 지시자
- 상위 클래스에 선언된 private 멤버 변수는 하위 클래스에서 접근할 수 없음
- 외부 클래스는 접근 할 수 없지만, 하위 클래스는 접근할 수 있도록 protected 접근 제어 지시자 사용
protected int customerId;
protected String customerName;
protected String customerGrade;
get()/set() 구현
- 접근 제어 지시자로 인해 접근할 수 없는 멤버변수에 접근하기위해 getter setter를 이용해 접근
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;
}
클래스 사용
- GoldCustomer 클래스로 생성한 인스턴스도 Customer 클래스에 생성된 매개변수나 메서드를 사용할 수 있다.
public class MainTest {
public static void main(String[] args) {
Customer customer_Lee = new Customer();
customer_Lee.setCustomerName("이성계");
customer_Lee.setCustomerId(10010);
customer_Lee.bonusPoint = 1000;
System.out.println(customer_Lee.showCustomerInfo());
GoldCustomer customer_jung = new GoldCustomer();
customer_jung.setCustomerName("정몽주");
customer_jung.setCustomerId(10020);
customer_jung.bonusPoint = 10000;
System.out.println(customer_jung.showCustomerInfo());
}
}
상속에서 클래스 생성 과정과 형변환
하위클래스 생성 과정
- 하위 클래스를 생성하면 상위 클래스가 먼저 생성
- new GoldCustomer()클래스를 호출하면 그 부모 클래스인 Customer() 생성자가 먼저 호출
- 클래스가 상속 받은 경우 하위 클래스의 생성자에서는 반드시 상위 클래스 생성자를 호출
public Customer() {
customerGrade = "SILVER";
bonusRatio = 0.01;
System.out.println("Customer클래스 생성자 호출");
}
public GoldCustomer() {
customerGrade = "GOLD";
bonusRatio = 0.05;
salesRatio = 0.1;
System.out.println("GOLD Customer클래스 생성자 호출");
}
- new GoldCustomer()클래스를 호출 시
- Customer 클래스 생성자가 먼저 호출되는 것을 확인할 수 있음
Customer클래스 생성자 호출
GOLD Customer클래스 생성자 호출
Super 키워드
- 하위 클래스에서 가지는 상위 클래스에 대한 참조 값
- super()는 상위 클래스의 기본 생성자를 호출 함
- 하위 클래스에서 명시적으로 상위 클래스의 생성자를 호출하지 않으면 super()가 호출됨 (이때 반드시 상위 클래스의 기본 생성자가 존재 해야함)
- 상위 클래스의 기본생성자가 없는 경우 (다른 생성자가 있는 경우) 하위 클래스에서는 생성자에서 super를 이용하여 명시적으로 상위클래스의 생성자를 호출 함
- super는 생성된 상위 클래스 인스턴스의 참조 값을 가지므로 super를 이용하여 상위 클래스의 메서드나 멤버변수에 접근할 수 있음
//부모 클래스의 생성자에 디폴트 생성자를 없애고 매개변수가 있는 생성자 추가
public Customer(int customerID, String customerName) {
this.customerId = customerID;
this.customerName = customerName;
customerGrade = "SILVER";
bonusRatio = 0.01;
System.out.println("Customer클래스 생성자 호출");
}
//자식 클래스의 생성자도 부모클래스의 생성자와 같은 형태를 유지해야함
//super 키워드를 이용하여 명시적으로 호출
public GoldCustomer(int customerID, String CustomerName) {
super(customerID,CustomerName);
customerGrade = "GOLD";
bonusRatio = 0.05;
salesRatio = 0.1;
System.out.println("GOLD Customer클래스 생성자 호출");
}
형 변환 (업 캐스팅)
- 상위 클래스로 변수를 선언하고 하위 클래스의 생성자로 인스턴스를 생성
Customer Customer_1 = new GoldCustomer(10030,"고객1");
- 상위 클래스 타입의 변수에 하위 클래스 변수 대입
- 하위 클래스는 상위 클래스의 타입을 내포하고 있으므로 상위 클래스로의 묵시적 형 변환이 가능함
- 상속 관계에서 모든 하위 클래스는 상위 클래스로 형변환(업 캐스팅) 됨 (역은 성립하지 않음)
형 변환과 메모리
Customer Customer_1 = new GoldCustomer(10030,"고객1");
- GoldCustomer() 생성자에 의해 GoldCustomer 클래스의 모든 멤버 변수에 대한 메모리는 생성되었지만, 변수의 타입이 Cusomer 이므로 실제 겁근 가능한 변수나 메서드는 Customer의 변수와 메서드이다.
메서드 재정의하기(overring)
- 오버라이딩(overriding): 상위 클래스에 정의된 메서드의 구현 내용이 하위 클래스에서 구현할 내용과 맞지 않는 경우 하위 클래스에서 동일한 이름의 메서드를 재정의 할 수 있다.
- GoldCustomer클래스는 Customer클래스와 할인율이 다르기때문에 메서드를 재정의 해야함
@Override
public int calcPrice(int price) {
bonusPoint +=price *bonusRatio;
return price - (int)(price * salesRatio);
}
@overriding 어노테이션(annotation)
- 애노테이션은 원래 주석이라는 의미
- 컴파일러에게 특별한 정보를 제공해주는 역활
- @overriding 애노테이션은 재정의 된 메서드라는 의미로 선언부가 기존의 메서드와 다른 경우 에러가남
형 변환과 오버라이딩 메서드 호출
Customer Customer_1 = new GoldCustomer(10030,"고객1");
Customer_1변수의 타입은 Customer지만 인스턴스의 타입은 GoldCustomer임 자바에서는 항상 인스턴스의 메서드가 호출됨