상속 = 계승 = 확장
자바에서는 클래스를 정의할 때 특정 클래스를 베이스로 해서 해당 클래스를 확장extends하는 식으로 새로운 클래스를 정의 가능
용어
상위 클래스 = 부모 클래스 = 슈퍼클래스 SuperClass = base class : 하위 클래스보다 일반적인 개념
하위 클래스 = 자식 클래스 = 서브클래스 SubClass = derived class : 상위 클래스보다 구체적인 클래스
문법
ectends 예약어 사용
ex) publicc class SubClass extends SuperClass
상속을 함으로 할수 있는 일
1) 하위 클래스가 상위 클래스의 변수와 메서드를 사용 할 수 있게 됨
2) 하위 클래스가 상위 클래스의 자료형으로 형 변환을 할 수 있게 됨
상속을 사용한 고객관리 프로그램
public class Customer {
protected int customerID; //고객 아이디
protected String customerName; //고객 이름
protected String customerGrade; //고객 등급
int bonusPoint; // 보너스 포인트
double bonusRatio; // 보너스 포인트 적립 비율
//protected 예약어로 선언한 변수를 외부에서 사용할 수 있도록 get set 메서드 추가
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() { //디폴트 생성자
customerGrade = "SILVER"; //기본 등급
bonusRatio = 0.01; // 보너스 포인트 기본 적립 비율
System.out.println("Customer() 생성자 호출 "); // 상위 클래스 생성할 때 콘솔 출력문
}
public int calcPrice(int price) { //보너스 포인트 적립, 지불 가격 계산 메서드
bonusPoint += price*bonusRatio; // 포인트 적립
return price; //지불 가격 return
}
public String showCustomerInfo() { // 고객정보 반환 메서드
return customerName + " 님의 등급은 " + customerGrade + "이며, 보너스 포인트는 "
+ bonusPoint +"입니다."; }
}
디폴트 생성자는 새로운 고객 한명이 생성될 때마다 디폴트 생성자에 들어있는 변수에 맞게 기본 설정을 해줌
단골고객에 대한 정보를 따로 생성하려면?
만약 장사가 잘되어 단골고객이 생겨서 단골 고객에게 열심히 하는 만큼는 보너스 포인트를 주기로 했다.
이 때, Customer 클래스에 단골고객에 대한 정보를 적게 되면 새로운 인스턴스 생성할 때 단골고객을 다루는 기능, 즉 일반 손님들을 위해서는 필요없는 기능까지 함께 생성되어 메모리 공간의 낭비 발생
고로 새로운 클래스를 만드는 것을 추천
Customer 클래스를 상속받은 하위 클래스 VIPCustomer 클래스
public class VIPCustomer extends Customer {
int agentID; // 고객상담원 아이디
double saleRatio; // 할인율
public VIPCustomer() { //디폴트 생성자
customerGrade = "VIP";
bonusRatio = 0.05;
saleRatio=0.1;
System.out.println("VIPCustomer() 생성자 호출");
}
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price - (int)(price*saleRatio);
}
public int getAgentID() {
return agentID;
}
}
main함수가 있는 CustomerTest2
public class CustomerTest2 {
public static void main(String[] args) {
Customer customerLee = new Customer(); // Customer 클래스를 사용할 인스턴스 생성
customerLee.setCustomerID(10010);
customerLee.setCustomerName("이순신");
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());
VIPCustomer customerKim = new VIPCustomer(); //하위 클래스인 VIPCustomer 객체 생성
customerKim.setCustomerID(10020);
customerKim.setCustomerName("김유신");
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
}
}
결과
하위 클래스의 인스턴스가 생성될 때는 꼭 상위 클래스의 인스턴스 생성 후 하위 클래스의 인스턴스가 생성 됨
Customer() 생성자 호출
이순신 님의 등급은 SILVER이며, 보너스 포인트는 1000입니다.
Customer() 생성자 호출 // 상위 클래스의 멤버 변수가 힙 메모리에 생성
VIPCustomer() 생성자 호출 // 이후 하위 클래스의 멤버 변수가 힙 메모리에 생성
김유신 님의 등급은 VIP이며, 보너스 포인트는 10000입니다.
위 결과에서
인스턴스가 생성될 때 하위 클래스 생성자에서 super()를 자동으로 호출하기 때문에 상위 클래스 생성자도 호출되는 것
예약어
super 예약어 : 상위 클래스의 주소, 즉 참조값을 알고 있음. 하위 클래스에서 상위클래스로 접근할 때 사용
업캐스팅 upcasting
상속받은 클래스 Sub Class 를 상속한 클래스 super Class 로 형 변환하는 것
ex) VIPCustomer 클래스로 인스턴스를 생성할 때 이 인스턴스의 자료형을 Customer형으로 클래스 형 변환하여 선언할 수 있음
Customer vc = new VIPCustomer();
: 상위클래스 Customer로 선언, VIPCustomer클래스의 인스턴스로 생성
형변환 후 vc 인스턴스가 사용할 수 있는 클래스의 자료형은 Customer로 한정되므로 vc 참조 변수가 가리킬 수 있는 변수와 메서드는 Customer 클래스에 있는 것들 뿐이다.
*형변환된, 업캐스팅된 인스턴스는 변수는 상위클래스에 있는 변수만 사용 가능하지만, 메서드는 하위 클래스에서 오버라이드된(재정의된) 메서드가 호출(사용)된다.
다운캐스팅
슈퍼클래스의 객체변수를 서브클래스의 객체변수에 대입
-반드시 명시적 타입 변환 지정
-업캐스팅 된 것을 다시 원래 형식으로 되돌리는 것
오버라이딩 method overriding
상위 클래스에 정의한 메서드가 하위 클래스에서 구현할 내용과 맞지 않을 경우, 하위 클래스에서 이 메서드를 재정의 가능하다
public class CustomerTest2 {
public static void main(String[] args) {
Customer customerLee = new Customer(10010, "이순신"); // Customer 클래스를 사용할 인스턴스 생성
/*
customerLee.setCustomerID(10010);
customerLee.setCustomerName("이순신");
*/
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());
VIPCustomer customerKim = new VIPCustomer(10010, "김유신", 2342); //하위 클래스인 VIPCustomer 객체 생성
/*
customerKim.setCustomerID(10020);
customerKim.setCustomerName("김유신");
*/
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showVIPInfo());
int price = 15000;
System.out.println(customerLee.getCustomerName() + "님이 지불해야 하는 금액은" + customerLee.calcPrice(price) +"원입니다.");
System.out.println(customerKim.getCustomerName() + "님이 지불해야 하는 금액은" + customerKim.calcPrice(price) +"원입니다.");
Customer vc = new VIPCustomer(10030, "나몰라", 2000); //VIP고객 생성, 업캐스팅
vc.bonusPoint = 1000;
System.out.println(vc.getCustomerName()+"님이 지불해야 하는 금액은" + vc.calcPrice(10000)+"원입니다.");
}
}
결과
Customer(int, String) 생성자 호출
이순신 님의 등급은 SILVER이며, 보너스 포인트는 1000입니다.
Customer(int, String) 생성자 호출
VIPCustomer(int, String) 생성자 호출
김유신 님의 등급은 VIP이며, 보너스 포인트는 10000입니다.김유신 님의 등급은 VIP이며, 상담원 아이디는 2342이고, 보너스 포인트는 10000입니다.
이순신님이 지불해야 하는 금액은15000원입니다.
김유신님이 지불해야 하는 금액은13500원입니다.
Customer(int, String) 생성자 호출
VIPCustomer(int, String) 생성자 호출
나몰라님이 지불해야 하는 금액은9000원입니다.
'자바 Java' 카테고리의 다른 글
문자열 표준 함수 / 문자열 처리 함수 (0) | 2019.10.30 |
---|---|
변수의 본질은 메모리 / 메모리의 종류 (0) | 2019.10.29 |
추상클래스 추상메서드 (0) | 2019.10.16 |
문자열 (0) | 2019.10.09 |
자료구조를 배우기 전의 C언어 기초 문법 (메모리/ 배열) (0) | 2019.10.09 |
댓글