상속(Inheritance)
공통된 특성을 가지는 부모(super,조상)클래스로부터 객체를 상속받아 자식(파생,sub)클래스에서 사용.
- 중복 제거, 재사용성 향상
- 객체 간에 is a kind of관계 성립
- 부모클래스의 멤버를 자식 클래스가 선언 없이 사용
- API 및 사용자가 만든 클래스들은 모두 상속관계인 계층구조로 되있다.
- 가장 상위의 클래스는 java.lang.Objeat(=최상위 클래스)
- 자바에서는 단일 상속. -> 계층구조 명확, 다이아몬드의 늪 방지
- 사용
부모가 먼저 생성되어야 자식이 사용할 수 있기 때문에 생성자가 필수로 있어야 한다.
자식 클래스의 생성자 첫 부분에서 부모 생성자 호출이 자동으로 발생. 명시하지 않으면 기본 생성자 호출.
package pack3;
//230106(1)
public class SangsokGrandFa {//final은 자식이 없다.(상속 불가)
private int nai=80; //private로 지정한 멤버와 생성자는 상속 불가
public String gabo="상감청자";
protected String gahun="착하게 살자";//패키지가 달라도 참조, 자식들만 참조 가능.
//부모가 먼저 생성되어야 자식이 사용할 수 있기 때문에 생성자가 필수로 있어야 한다.
// 자식 클래스의 생성자 첫 부분에서 부모 생성자 호출이 자동으로 발생. 명시하지 않으면 기본 생성자 호출.
public SangsokGrandFa() {
//-> SangsokGrandFa의 부모가 Object이기 때문에 Object 기본 생성자 호출.
//(모든 클래스에서 Object가 포함하는 메서드를 언제든지 사용)
System.out.println("할아버지 생성자");
}
public SangsokGrandFa(int nai) {
this.nai=nai;
System.out.println("생성자)할아버지 나이: "+this.nai);
}
public void say() {
System.out.println("할아버지 말씀: IT를 배워라");
}
void eat() {
System.out.println("밥은 맛있게...");
}
public int getNai() {
return nai;
}
}
package pack3;
//230106(1)
public class SangsokFather extends SangsokGrandFa{//부모자식 성립
private int nai;//은닉화
public String gabo="물병";
private final int house=1;//수정 불가.
public SangsokFather() {
//제일 처음에 부모 생성자 호출해야.
super(9); //부모 생성자는 상속이 안되기 때문에 super를 통한 방법으로만 호출 가능
//super(); //부모 생성자 생략 가능.
//private가 먼저인듯.
System.out.println("아버지 기본");
}
public SangsokFather(int nai) {//매개변수가 있는 생성자를 호출.
super(nai);
//this(); //자기가 자기의 생성자 호출 (아규먼트 없는 생성자)
}
@Override
// 오버라이드 강요 <- 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공
public int getNai() {
int q=0;
System.out.println("아버지의 할아버지 나이 "+super.getNai());
return nai;
}
@Override
public void say() {
System.out.println("아버지 말씀: 건강도 지켜라");
}
public int getHouse() {//아버지 고유 메소드
return house;
}
public void showData() {
String gabo="꽃병";
System.out.println("가보는 "+gabo);///지역변수 출력
System.out.println("가보는 "+this.gabo);//현재 클래스꺼
System.out.println("가보는 "+super.gabo);//부모꺼
this.say();
super.say();
System.out.println("가훈은 "+this.gahun);//현재 클래스에서 찾고 없으면 올라감
System.out.println("가훈은 "+super.gahun);//무조건 올라감
this.eat();
super.eat();
}
}
package pack3;
//230106(1)
final public class SangsokMe extends SangsokFather{
//final은 자식이 없다. 상속 안 할 거
public SangsokMe(){
System.out.println("내 생성자");
}
//없는 건 위에 가서 찾음.
//상속은 복사가 아니라 이동
public void biking() {
System.out.println("자전거로 전국일주");
}
}
package pack3;
//230106(1)
public class SansockGajok {
public static void main(String[] args) {
// 상속에 대하여
System.out.println("할아버지----------");
// SangsokGrandFa granFa = new SangsokGrandFa();
// System.out.println("가보 : "+granFa.gabo);
// System.out.println("가훈 : "+granFa.gahun);
// System.out.println("할 나이 : "+granFa.getNai());
// granFa.say();
// granFa.eat();
// System.out.println();
// SangsokGrandFa granFa2 = new SangsokGrandFa(82);//매개변수가 있는 생성자 호출+
// System.out.println("가훈 : "+granFa2.gahun);
// System.out.println("할2 나이 : "+granFa2.getNai());
// granFa2.say();
// System.out.println("\n아버지----------");
// SangsokFather father1 = new SangsokFather();
// SangsokFather father = new SangsokFather(100);
// //프라이빗 빼고 다 상속.
// father.showData();
// System.out.println("가보 : "+father.gabo);
// System.out.println("가훈 : "+father.gahun);
// System.out.println("아버지 나이 : "+father.getNai());
// System.out.println("아버지1 나이 : "+father1.getNai());
//
// father.say();
// father.eat();
// System.out.println("할 나이 : "+granFa.getNai());
// System.out.println("집 :"+father.getHouse()+"채");
System.out.println("나------------");
SangsokMe me =new SangsokMe();
//위에서부터 쭉 상속.
System.out.println("가보 : "+me.gabo);
System.out.println("가훈 : "+me.gahun);
System.out.println("내 나이 : "+me.getNai());
me.say();
me.eat();
System.out.println("집 :"+me.getHouse()+"채");
me.biking();
System.out.println("===========");
me.showData();//아버지에 있는 메소드 출력
}
}