본문 바로가기
java

Java-1강 상속

by 킹차니 2021. 2. 21.

상속

class A {
 	멤버변수;
	메서드;
}

class B extends A{
	A의 멤버변수;
    A의 메서드;
}

상속: 무언가를 물려받는다. 

자바에서 B클래스는 A클래스를 상속 받을 수 있다. 

이렇게 되면 B클래스는 A클래스의 멤버변수와 메서드를 사용할 수 있게된다. 상속할 할 때는 extends예약어를 사용한다.

 

예를 들면 사람은 포유류에 속한다. 이 때 포유류는 상위클래스(=superclass, baseclass)가 되고, 사람은 하위클래스(=subclass, derivedclass)가 된다. 사람은 포유류의 많은 특성을 갖지만 사람만의 차별되는 특성도 있을 것이다. 그러한 특성은 사람클래스에 따로 정의해주면 된다.

 

예시)

고객정보 서비스를 제공하기위해 일반 고객 클래스와 VIP고객 클래스를 만드는 경우를 생각해보자.

이때 VIP고객 클래스를 일반 고객의 클래스를 상속받아 만들수 있다.

package ineritance;

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() {
//		customerGrade = "SILVER";
//		bonusRatio = 0.01;
//		System.out.println("Customer()생성자 호출");
//	}
	
	public Customer(int customerID, String customerName) {
		this.customerID = customerID;
		this.customerName = customerName;
		customerGrade = "SILVER";
		bonusRatio = 0.01;
//		System.out.println("Customer(int, String)생성자  호출.");
	}
	public int calcPrice(int price){
		bonusPoint += price * bonusRatio;
		return price;
	}
	
	public String showCustomerInfo() {
		return customerName+ "님의 등급은 " + customerGrade + "이며, 보너스 포인트는 현재 " +bonusPoint+"입니다.";
	}
}

protected 예약어는 외부에서는 접근할 수 없지만 하위 클래스에서는 사용할 수 있도록 지정하는 예약어이다. 외부에서는 private과 동일하게 동작한다.

이제 protected예약어로 선언한 변수는 외부 클래스에서 setter와 getter를 이용하여 값을 지정할 수 있다.

일반 고객 클래스를 상속받은 VIP고객 클래스를 보자.

package ineritance;

public class VIPCustomer extends Customer{
	private int agentID;
	double saleRatio;
	
	@Override //  이 메서드는 재정의 된 메서드입니다.
	public int calcPrice(int price){
		bonusPoint += price*bonusRatio;
		return price - (int)(price*saleRatio);
	}
	

	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)생성자 호출");
	}
//	public VIPCustomer() {
//		customerGrade = "VIP";
//		bonusRatio = 0.05;
//		saleRatio = 0.1;
//		System.out.println("VIPCustomer()생성자 호출");
//	}
	
	public String showVIPInfo() {
		return super.showCustomerInfo()+"담당 상담원은의 직원번호는 "+agentID+"입니다.";
	}
	
	public int getAgentID() {
		return agentID;
	}
}

VIP고객 클래스는 일반 고객과 다르게 agentID라는 멤버변수가 추가되었다. 또한 calcPrice 메서드가 일반 고객의 것과는 다르다.

VIP의 가격계산메서드는 할인이 적용된 금액을 계산하는 기능이 추가되어 @Override 어노테이션을 이용해 수정된 것이다.

 

또한 super라는 예약어가 있는데, 이는 상위클래스의 컨스트럭터를 호출하는 예약어이다. super는 상위 클래스의 참조값을 가지고 있다.

 

하위 클래스가 생성될 때 하위 클래스의 Constructor만 호출되는 것이 아니라, 하위 클래스 내에 super(); 코드가 자동으로 생성되어

상위 클래스의 디폴트 생성자를 호출한다.  우리가 정의한 일반 고객의 클래스는 인자 2개 있는 생성자이므로 하위 클래스에서도 그에 맞는

인자를 전달하는 super()예약어를 적어두어야 에러없이 인스턴스를 생성할 수 있다.

 

위의 코드를 테스트해보자.

package ineritance;

public class CustomerTest1 {

	public static void main(String[] args) {
		Customer lee = new Customer(100, "이씨");
		System.out.println(lee.showCustomerInfo());
		
		VIPCustomer kim = new VIPCustomer(101, "김씨", 1);
		System.out.println(kim.showVIPInfo());
	}
}

 

출력결과를 보면 다음과 같다.

 

이씨님의 등급은 SILVER이며, 보너스 포인트는 현재 0입니다.

김씨님의 등급은 VIP이며, 보너스 포인트는 현재 0입니다.또한 담당직원의 직원번호는 1입니다.

 

주목해야할 것은 VIP고객 클래스 showVIPInfo메서드이다. 일반 고객클래스의 showCustomerInfo메서드를 실행하기위해 super.showCustomerInfo()으로 상위 클래스의 메서드를 호출한 뒤에

+"담당 상담원은의 직원번호는 "+agentID+"입니다.";

를 추가하였다. super는 상위 클래스에 선언한 멤버변수나 메서드를 하위클래스에서 참조할 때에도 사용된다.