본문 바로가기

카테고리 없음

Java day5

7. 메서드 재정의

 

상위 클래스에 정의된 메서드가 하위클래스에 맞지 않을 때

하위클래스에서 재정의하는 것= 오버라이드

이름, 반환값, 매개변수는 동일

package inheritance;

public class Membership {
	private int memberId;
	protected String memberName;
	protected int bonusPoint;
	protected double bonusRatio;
	protected String membership;
	
	public Membership(int memberId, String memberName) {
		this.memberId=memberId;
		this.memberName=memberName;
		membership="Silver";
		bonusRatio=0.01;
	}
	
	public int calcPrice(int price) {
		bonusPoint+=price*bonusRatio;
		return price;
	}
}
package inheritance;

public class GoldMembership extends Membership{
	
	private double salesRatio;
	
	// 디폴트가 없으면 Add Constructor를 하도록 창이 뜸
	public GoldMembership(int anything, String anything2) {
		super(anything, anything2); // 상위 클래스 생성자를 호출
		
		membership="Gold";
		bonusRatio=0.05;
		salesRatio=0.05;
		
	}

	@Override //annotation compiler에게 재정의된 메서드라는 것을 알려줌. 없으면 다른 메서드로 인식
	public int calcPrice(int price) {
		bonusPoint+=price*bonusRatio;
		price-=price*salesRatio;
		return price;
	}

	public double getSalesRatio() {
		return salesRatio;
	}

	public void setSalesRatio(double salesRatio) {
		this.salesRatio = salesRatio;
	}
	
	
}
package inheritance;

public class MembershipTest {
	
	public static void main(String[] args) {
		Membership memberLee= new Membership(1002,"Lee");
		GoldMembership memberKim= new GoldMembership(1010,"Kim");
		
		Membership memberPark= new GoldMembership(888,"Park");
		
		int price=10000;
		
		int memberPrice=memberLee.calcPrice(price);		
		int goldPrice=memberKim.calcPrice(price); //GoldMembership의 override된 calcPrice를 호출함
		int parkPrice=memberPark.calcPrice(price);
		
		System.out.println(memberPrice); //10000
		System.out.println(goldPrice); //95000
		System.out.println(parkPrice); //95000
		
	}

}

parkPrice == 95000인 이유 🙄

메서드나 멤버변수가 불리는 기준은 자료형 -> 멤버십으로 선언된 memberPark은 멤버십으로 불려야 되는 게 맞는데

c++에서 나온 자바는 c++의 가상함수 개념과 같은 가상 메서드의 개념이 적용되어 모든 메서드가 가상메서드임

-> 가상 메서드 방식에 의해 골드 회원 인스턴스의 메서드가 호출됨

 

private으로 선언된 salesRatio 변수에는 다운캐스팅을 하지 않으면 접근이 불가하지만 메서드는 골드의 메서드를 불러온다????????? 맞아???????

 

가상메서드

프로그램에서 어떤 객체의 변수나 메서드의 참조는 그 타입에 따라 이루어짐

가상 메서드는 타입과 상관없이 실제 생성된 인스턴스의 메서드가 호출됨

 

가상메서드를 통해서 다형성을 구현할 수 있음

하나의 코드가 여러 자료형으로 구현됨

객체 지향 프로그래밍의 유연성, 재활용성, 유지보수성의 기본이 됨

package polymorphism;

import java.util.ArrayList;

import inheritance.GoldMembership; // ctrl + shift + o
import inheritance.Membership;

public class PolymorphismTest {
	
	public static void main(String[] args) {
		
		ArrayList<Membership> memberList = new ArrayList<Membership>();
		Membership memberLee = new Membership(1001,"Lee");
		Membership memberKim= new GoldMembership(1002,"Kim");
		// Lee와 Kim 모두 멤버십으로 선언되었기 때문에 memberList에 넣을 수 있음
		
		memberList.add(memberLee);
		memberList.add(memberKim);
		
		int price=1000;
		for(Membership member:memberList) {
			int newPrice = member.calcPrice(price);
			// 각 멤버십 클래스에서 calcPrice 메서드만 오버라이드하면 member 인스턴스에 정의된 calcPrice에 따라서 
			// 하나의 코드에 의해서 여러 구현(여러 등급의 멤버십의 가격에 따른 가격을 계산)이 가능함
			// 다형성=>인스턴스에 따라서 다른 메서드가 호출됨
			System.out.println(newPrice);
		}
	}

}

상속을 사용하게 되면 클래스간 결합도가 증가하기 때문에 클래스간의 상하관계가 명확한 경우만 상속을 사용함