상속, Overriding에 대한 복습
상속
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로 보호받기 때문에 재정의가 되지 않아 에러가 난다.