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
}
}
}