상속 관계와 접근 제어에 대해 알아보자. 참고로 접근 제어를 자세히 설명하기 위해 부모와 자식의 패키지를 따로 분리하였다.
이 부분에 유의해서 예제를 만들어보자.
접근 제어자를 표현하기 위해 UML 표기법을 일부 사용했다.
접근 제어자를 잠시 복습해보자.
접근 제어자의 종류
순서대로 private 이 가장 많이 차단하고, public 이 가장 많이 허용한다.
private -> default -> protected -> public
그림과 같이 다양한 접근 제어자를 사용하도록 코드를 작성해보자.
package access.parent;
public class Parent {
public int publicValue;
protected int protectedValue;
int defaultValue;
private int privateValue;
public void publicMethod() {
System.out.println("public method");
}
protected void protectedMethod() {
System.out.println("protected method");
}
void defaultMethod() {
System.out.println("default method");
}
private void privateMethod() {
System.out.println("private method");
}
public void printParent() {
System.out.println("==Parent 메서드 안==");
System.out.println("publicValue = " + publicValue);
System.out.println("protectedValue = " + protectedValue);
System.out.println("defaultValue = " + defaultValue);
System.out.println("privateValue = " + privateValue);
// 부모 메서드 안에서 모두 접근 가능
defaultMethod();
privateMethod();
}
}
package access.child;
import access.parent.Parent;
public class Child extends Parent {
public void call() {
publicValue = 1;
protectedValue = 2; // 상속 관계 or 같은 패키지에서만 접근 가능
// defaultValue = 3; // 다른 패키지에서 접근 불가, 컴파일 오류
// privateValue = 4; // 접근 불가, 컴파일 오류
publicMethod();
protectedMethod(); // 상속 관계 or 같은 패키지에서만 접근 가능
// defaultMethod(); // 다른 패키지에서 접근 불가, 컴파일 오류
// privateMethod(); // 접근 불가, 컴파일 오류
printParent();
}
}
package access;
import access.child.Child;
public class ExtendsAccessMain {
public static void main(String[] args) {
Child child = new Child();
child.call();
}
}
public method
protected method
==Parent 메서드 안==
publicValue = 1
protectedValue = 2
defaultValue = 0
privateValue = 0
default method
private method
둘의 패키지가 다르다는 부분에서 유의하자.
자식 클래스인 Child에서 부모 클래스인 Parent 에 얼마나 접근할 수 있는지 확인해보자.
메서드의 경우도 앞서 설명한 필드와 동일하다.