01 상속
1. 상속(inheritance): 클래스 간의 관계, 물려 받는 것
ex) B클래스가 A클래스를 상속받으면 B클래스는 A클래스의 멤버 변수와 메서드를 사용 가능하다
1) 클래스의 상속
① 상속 예약어 extends
- A 클래스가 가지고 있는 속성이나 기능을 추가로 확장하여 B 클래스를 구현한다는 의미
ex) class B extends A { }
예제: 고객 관리 프로그램 구현하기
Doit! 자바 프로그래밍 입문
* Customer Class: 고객 아이디, 이름, 등급, 보너스 포인트, 보너스 포인트 적립 비율
* VIPCustomer Class: 고객 아이디, 이름, 등급, 보너스 포인트, 보너스 포인트 적립 비율, 할인율
* VIP Customer는 항상 10% 할인 + 보너스 포인트 5% 적립
ex) Customer.java
package com.inheritance;
public class Customer {
protected int customerID;
protected String customerName, customerGrade;
int bonusPoint;
double bonusRatio;
public Customer(int customerID, String customerName, int bonusPoint) {
super();
this.customerID = customerID;
this.customerName = customerName;
this.bonusPoint = bonusPoint;
customerGrade = "SILVER"; // 기본 고객의 등급은 실버
bonusRatio = 0.01; // 실버 등급의 보너스 포인트 비율
}
int calcPrice(int price) {
bonusPoint = bonusPoint + (int)(price * bonusRatio); // 포인트 계산
return price;
}
void showCustomerInfo() { // 고객 정보 출력
System.out.println(customerName + "님의 등급은 " + customerGrade + "이며, 보너스 포인트는 " + bonusPoint + "입니다.");
}
}
ex) VIPCustomer.java
package com.inheritance;
public class VIPCustomer extends Customer{
double saleRatio;
public VIPCustomer(int customerID, String customerName, int bonusPoint) {
super(customerID, customerName, bonusPoint);
customerGrade = "VIP"; // VIP 등급의 고객
bonusRatio = 0.05; // VIP 등급의 보너스 포인트 비율
saleRatio = 0.1; // VIP 등급의 세일 비율
}
@Override
int calcPrice(int price) { // VIP 등급의 할인된 가격과 보너스 포인트 계산
bonusPoint = bonusPoint + (int)(price * bonusRatio);
return price - (int)(price * saleRatio);
}
}
① 3행: VIPCustomer 클래스는 Customer 클래스를 상속받아 Customer 클래스에 선언되어 있는 customerID, customerName, customerGrade, bonusPoint, bonusRatio 멤버 변수와 calcPrice(), sowCustomerInfo() 메서드를 사용 가능
② Customer.java의 3행,4행: Customer 클래스에서 private으로 선언한 변수들은 외부 클래스에서 사용할 수 없음 > protected 예약어 사용
* private: 외부 클래스에서 사용 불가능
protected: 외부 클래스에서 사용할 수 없지만 하위 클래스에서는 사용 가능
ex) CustomerTest.java
package com.inheritance;
public class CustomerTest {
public static void main(String[] args) {
Customer lee = new Customer(10010, "이순신", 1000); // 고객ID, 이름, 현재포인트
lee.showCustomerInfo();
VIPCustomer kim = new VIPCustomer(10020, "김유신", 5000); // VIP고객ID, 이름, 현재포인트
kim.showCustomerInfo();
int price = 10000; // 10000원을 구매할 때 기본 고객과 VIP고객의 가격 차이
System.out.println(lee.customerName + "님이 지불하실 금액은 " + lee.calcPrice(price) + "원 이고 현재 보너스 포인트는 " + lee.bonusPoint + "입니다.");
System.out.println(kim.customerName + "님이 지불하실 금액은 " + kim.calcPrice(price) + "원 이고 현재 보너스 포인트는 " + kim.bonusPoint + "입니다.");
}
}
[결과화면]
위 코드들을 그림으로 표현하자면 아래와 같다.
③ 예약어 super
- 하위 클래스가 생성될 때는 상위 클래스의 생성자가 먼저 호출된다
- 하위 클래스에서 상위 클래스로 접근할 때 super 예약어를 사용한다
- 하위 클래스는 상위 클래스의 주소(참조 값)을 알고 있고 이 참조 값을 가지고 있는 예약어가 super
- 상위 클래스에 생성자 코드가 따로 없으면 super 예약어로 상위 클래스의 디폴트 생성자가 자동으로 호출된다
- 상위 클래스에 디폴트 생성자가 없고 매개변수가 있는 생성자만 있을 경우 super 예약어에 매개변수를 추가하여, 매개변수가 있는 상위 클래스의 생성자를 직접 호출해야 한다
- 현재 클래스 지정: this() / 부모 클래스 지정: super()
[결과화면]
2. 오버라이딩 (Overriding)
- 상위 클래스에 정의한 메서드가 하위 클래스에서 구현할 내용과 맞지 않을 경우, 하위 클래스에서 메서드를 재정의하는 것
- 오버라이딩을 하려면 반환형, 메서드 이름, 매개변수 개수, 매개변수 자료형이 반드시 같아야 한다
오버라이딩 방법 ①
ex) calcPrice.java
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price;
}
ex) VIPCustomer.java
package inheritance;
public class VIPCustomer extends Customer {
private int agentID;
double saleRatio;
@Override
public int calcPrice(int price) {
bonusPoint += price * bonusRatio;
return price - (int)(price * saleRatio);
}
① 7행: 하위 클래스 (VIPCustomer)의 calcPrice() 메서드 재정의
상위 클래스의 메서드와 매개변수의 자료형, 개수, 반환형을 같게 설정
오버라이딩 방법 ②
(1) 코드에서 오른쪽 마우스 클릭
(2) [Source] > [Override/Implement Methods...]
(3) 재정의할 메서드 선택
package inheritance;
public class VIPCustomer extends Customer {
private int agentID;
double saleRatio;
@Override // 애노테이션(annotation): "이 메서드는 재정의된 메서드입니다"라고 컴파일러에 명확히 알려주는 역할
public int calcPrice(int price) {
// TODO Auto-generated method stub
return super.calcPrice(price);
}
02 다형성
1. 다형성(polymorphism)
- 하나의 코드가 여러 자로형으로 구현되어 실행되는 것 = 같은 코드에서 여러 실행 결과가 나오는 것
ex) 다형성 예제
package polymorphism;
class Animal {
public void move() {
System.out.println("동물이 움직입니다.");
}
}
class Human extends Animal{
public void move() {
System.out.println("사람이 두 발로 걷습니다.");
}
}
class Tiger extends Animal{
public void move() {
System.out.println("호랑이가 네 발로 뜁니다.");
}
}
class Eagle extends Animal{
public void move() {
System.out.println("독수리가 하늘을 납니다.");
}
}
public class AnimalTest1{
public static void main(String[] args) {
AnimalTest1 aTest = new AnimalTest1();
aTest.moveAnimal(new Human());
aTest.moveAnimal(new Tiger());
aTest.moveAnimal(new Eagle());
}
public void moveAnimal(Animal animal) {
animal.move(); // 재정의된 메서드가 호출됨
}
}
① 어떤 인스턴스가 매개변수로 넘어와도 모두 Animal 형으로 반환
② 36행: Animal에서 상속받은 클래스가 매개변수로 넘어오면 모두 Animal형으로 반환되므로 animal.move() 메서드를 호출 가능
* animal.move() 메서드는 Animal의 move가 아닌 매개변수로 넘어온 실제 인스턴스의 메서드
* animal.move() 코드는 변함이 없지만 어떤 매개변수가 넘어왔느냐에 따라 출력문이 달라짐
[결과 화면]
2. 다형성의 장점
① 확장성: 상위 클래스를 상속받아 하위 클래스를 구성하면 모든 클래스를 상위 클래스 자료형 하나로 쉽게 관리 가능
② 유지보수가 편리: 상위 클래스에서 공통 부분의 메서드를 제공하고, 하위 클래스에서는 그에 기반한 추가 요소를 덧붙여 구현하면 코드 양도 줄어들고 유지보수도 편리
'STUDY > Java' 카테고리의 다른 글
[JAVA] 데이터 타입 - 기본타입, 참조타입 (0) | 2021.11.05 |
---|---|
[JAVA] 추상 클래스, 인터페이스 (0) | 2021.11.05 |
[JAVA] 제어문(if, switch), 반복문(for, while, do while), 배열, ArrayList (0) | 2021.11.05 |
[JAVA] this, static 변수 (0) | 2021.11.05 |
[JAVA] 변수, 자료형, 상수, 형변환 (0) | 2021.10.20 |