Java/Java icia 19일차

상속, Overriding에 대한 복습

swkn 2023. 3. 20. 10:20

상속

 

1. 상속 ( inheritance )

자바에서의 상속은 부모클래스( 물려주는 클래스 ) , 자식클래스 ( 물려받는 클래스 ) 존재

부모클래스가 가진 필드 , 생성자 , 메소드를 자식 클래스가 물려받는 것

단 , private로 접근제한자가 붙은 것은 상속 불가하다.

 

public ParentClass{

}

public childClass extends ParentClass {

}

//상속클래스의 문법

 

1 - 1 메소드 재정의

부모클래스가 가진 메소드를 자식이 재정의한다.

재정의하는 부분은 메소드의  실행 블록이다

메소드의 리턴타입 , 메소드이름 , 매개변수는 변경불가하다.

@override
public void method1(String var1){

}

//오버라이드 메소드의 문법

 

1 - 2 @ < Annotation ( 어노테이션 )

컴파일 단계에서 체크하는 것 ( @override )

있고 없고의 차이에는 아래와 같다

public ParentClass {
public void method1(String var1){
 }
}

public ChildClass extends ParentClass {
//@override 가 없으면 오류, 문법체크를 해줌
public void method1(String var1){
  }
 }

 

2. 상속 , Override 예제

package classic;

public class ParentClass {
	//필드
	public String name;
	
	//생성자
	public ParentClass() {
		System.out.println("부모 기본 생성자");
	}

}

부모클래스에서 필드 name 선언 , 기본생성자 생성

package classic;

public class ChildClass extends ParentClass {

}

부모클래스를 상속받는다.

package classic;

public class InheritanceMain {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//부모 객체
		ParentClass p1 = new ParentClass();
		p1.name = "name1";
		System.out.println(p1.name);
		
		//자식객체
		ChildClass c1 = new ChildClass();
		c1.name = "자식 name1";
		System.out.println(c1.name);
	}

}
부모 기본 생성자
name1
부모 기본 생성자
자식 name1

child 클래스는 아무것도 없는데도 상속받아서 c1.name이 사용가능해진 것이다.

출력된 것을 보면 

ChildClass c1 = new ChildClass(); 문에서 부모 기본 생성자가 출력된 것으로 보아서

자식 생성자로 생성되더라도 부모 생성자가 호출된다.

 

package classic;

public class ChildClass extends ParentClass {
	public ChildClass() {
		System.out.println("자식 클래스 생성자");
	}


}

ChildClass에서 생성자가 생성될때 "자식 클래스 생성자"가 출력되게 해보면

Main에서 다시 출력을 찍어보면

부모 기본 생성자       //      ParentClass p1 = new ParentClass();
name1                 //       System.out.println(p1.name);
부모 기본 생성자
자식 클래스 생성자    //       ChildClass c1 = new ChildClass();
자식 name1            //       System.out.println(c1.name);

이렇게 출력되게 된다.

 

확실하게 부모클래스 생성자가 호출된 후 자식클래스 생성자까지 출력된 후 name메소드가 출력된 것을 볼 수 있다.

 

package classic;

public class ParentClass {
	//필드
	public String name;
	
	//생성자
	public ParentClass() {
		System.out.println("부모 기본 생성자");
	}
	
	//메소드
	public void hello() {
		System.out.println("부모 hello");
	}

}

부모클래스에 hello 메소드를 추가

package classic;

public class InheritanceMain {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//부모 객체
		ParentClass p1 = new ParentClass();
		p1.name = "name1";
		System.out.println(p1.name);
		
		//자식객체
		ChildClass c1 = new ChildClass();
		c1.name = "자식 name1";
		System.out.println(c1.name);
		c1.hello();
	}

}

Main에서 c1.hello(); 메소드를 출력하면

부모 기본 생성자
name1
부모 기본 생성자
자식 클래스 생성자
자식 name1
부모 hello

부모 클래스의 메소드가 출력된다.

이상태에서

package classic;

public class ChildClass extends ParentClass {
	public ChildClass() {
		System.out.println("자식 클래스 생성자");
	}
	//hello 재정의
	@Override
	public void hello() {
		System.out.println("자식 hello");
	}


}

자식클래스에서 hello 메소드를 재정의하게 되면

부모 기본 생성자
name1
부모 기본 생성자
자식 클래스 생성자
자식 name1
자식 hello

자식 클래스의 오버라이딩 된 메소드가 출력된다.

 

@Override로 붙여준 메소드는 메소드명을 바꾸면 에러가 나게 되는데 , 재정의하도록 되어있는데 메소드명을 바꾸면 

다른 메소드가 되기 때문에 에러가 나게 되어있다. ( 리턴타입을 수정해도 마찬가지 )

부모 클래스가 선언한 그대로의 리턴 타입 , 메소드 명을 사용해야 한다.

 

	private void hi() {
		System.out.println("부모 hi");
	}

부모 클래스에 hi 라는 private로 접근제한한 메소드를 만들었다.

@Override
	public void hi() {
		System.out.println("자식 hi");
	}

자식클래스에서 hi 라는 public 인 메소드를 재정의하려고 해도

private로 보호받기 때문에 재정의가 되지 않아 에러가 난다.