본문 바로가기

카테고리 없음

Java day4

6. 상속과 형변환

 

상위 클래스 - 하위 클래스

parnet/super/base class - child/sub/derived class

general한 추상적인 클래스 -  구체적인 클래스

 

단일 상속만 가능

extends 상위 클래스 형태

 

private으로 선언한 멤버변수는 하위 클래스(골드 멤버십) 인스턴스에서 사용할 수 없음 -> 해당 변수가 인스턴스에서 생성이 안되는 건 아니고 접근만 불가

protedted로 선언한 멤버변수만 인스턴스. 하면 리스트업됨 

 

하위 클래스가 상위 클래스를 상속받고 하위 클래스의 인스턴스가 생성될 때 항상 상위 클래스가 먼저 생성된다

 

package inheritance;

public class Membership {
	private int memberId;
	private String memeberName;
	private int bonusPoint;
	protected int bonusRatio;
	protected String membership;
	
	public Membership() {
		this.membership="silver";// 인자로 헷갈리는 부분이 없어서 this를 안써도 되는듯?
//		membership="silver";
		System.out.println("멤버쉽 클래스 생성");
	}
}
package inheritance;

//멤버십 클래스를 상속받은 하위 클래스
public class GoldMembership extends Membership{
	//하위 클래스가 상위 클래스의 멤버 변수에 접근하기 위해서는 private대신 protected접근 제한자를 사용해야함
	//-> bonusRatio와 membership만 불러올 수 있음
	
	public GoldMembership() {
		
		membership="Gold";
		System.out.println("골드 멤버쉽 클래스 생성");

	}
	/*
	* membership="Gold";// Syntax error on token "membership", VariableDeclaratorId expected after this token
	* Procedural code cannot be written directly in a class definition. The code is causing syntax errors 
	* because it's not legal to do so.
	* Instead, put the code in an appropriate method or initialization block.
	* Here, method would be better --> 실제로 예제에서 골드 멤버십 메서드 안에 넣음
	*/

}
package inheritance;

public class MembershipTest {
	
	public static void main(String[] args) {
//		Membership memberLee = new Membership();
		GoldMembership memberKim= new GoldMembership();
		/*
		 * 멤버쉽 클래스 생성
		 * 골드 멤버쉽 클래스 생성
		 * -> 상위 클래스가 먼저 호출되는 이유는 골드 멤버십 메소드에서 super() 메서드가 임의로 호출되기때문인데
		 * 이 때 상위 클래스의 생성자가 호출된다 -> 매개 변수가 없으면 default constructor를 호출함
		 */
	}

}

super()

- 하위 클래스가 가지는 상위 클래스에 대한 레퍼런스

- 하위 클래스에서 상위 클래스의 멤버 변수와 메소드에 접근할 때 사용함

- 상위 클래스의 생성자를 호출

 

아무것도 없을 때는 super() 로 default constructor가 호출되지만

super()메서드를 오버로드하면   default constructor가 없기때문에 super()메서드를 쓰면 해당 부분에서, 안쓰면 상속받는 클래스에서 에러가 남

오버로드한 형식을 따라서 super메서드를 호출해주면 됨

 

기본 생성자가 없을 때 super를 사용해서 상속받기

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;
	}
}
package inheritance;

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

	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");
		// 상위 클래스로 묵시적 형 변환이 허용됨
		// 타입(형)을 Membership으로 지정하였으므로 사용할 수 있는 변수와 메서드는 Membership 클래스에 한정된다 
		// -> private으로 지정된 salesRatio에 접근할 수 없음
		
		System.out.println("Park's Membership: "+ memberPark.membership);// Gold
		
		if(memberPark instanceof GoldMembership) {
			GoldMembership gMember= (GoldMembership) memberPark; // 다운캐스팅할 때는 다운캐스팅할 클래스를 명시해주어야함
																 // 업캐스팅시에는 필요 없음
			/* ※주의※ 
			 * memberPark이 GoldMembership가 아니더라도 
			 * gMember의 타입과 ()안의 다운캐스팅하는 부분의 타입이 같으면 컴파일에러가 나지 않음
			 * -> memberPark의 타입을 확인해주는 instanceof 메서드를 사용
			 */
			gMember.setSalesRatio(0.1);
			System.out.println("Park's Sales Ratio: "+ gMember.getSalesRatio());//0.1
			
		}
	}

}