JAVA/JAVA
Java | 접근 제어자 with 상속
pathas
2020. 1. 30. 17:40
접근 제어자 with 상속
클래스, 생성자, 멤버 변수, 메소드에 외부에서의 접근 가능성을 제어하는 것
접근 제어자 | 설명 |
---|---|
public | 외부 패키지 및 외부 클래스 어디에서나 접근 가능 단, 멤버 변수와 메소드가 public이더라도 해당 클래스가 public이 아니면 외부 패키지에서는 접근 불가 하나의 java(class)파일에는 하나의 public 클래스만 작성 가능 |
protected | 같은 패키지 내부와 상속 관계의 클래스에서만 접근할 수 있고 그 외 클래스에서는 접근 불가 외부 패키지에 있는 클래스여도 같은 패키지의 클래스를 상속받았다면 접근 가능 데이터를 캡슐화하면서 외부 패키지에서도 상속이 가능하도록 하는 접근 제어자 |
아무것도 없는 경우 | default이며 같은 패키지 내부에서만 접근 가능, 동일 패키지의 클래스를 상속받은 외부 패키지의 자식 클래스도 접근 불가 같은 패키지 안에서만 상속 가능 |
private | 같은 클래스 내부에서만 접근 가능하며 어떠한 종류의 상속도 허가하지 않음 |
※ 최상위 클래스 선언에서는 private, protected 사용 불가
import
외부 패키지에 존재하는 클래스를 현재 클래스로 불러올 때 사용
같은 패키지에 있는 다른 클래스는 자동 인식(import할 필요 없음)java.lang 패키지는 기본패키지로 자동으로 import됨, [import java.lang.*]이 생략된 것
그 외 패키지는 무조건 import를 해야 사용할 수 있음
사용법
import 최상위 패키지명.하위 패키지명.클래스명;
// import는 대체로 소스코드 가장 위쪽에 작성
// 패키지명.*; 작성시, 해당 패키지의 모든 클래스를 불러옴
사용례
두 개의 패키지에 세 개의 클래스를 만들어서 접근 제어자에 따른 접근 가능성에 대해 확인
j200130.test package
A.java
package j200130.test;
public class A {
// Private
private int i = 10;
// Default
int j;
// Protected
protected int k;
// Public
public int m;
// Private, 자기 클래스 내부에서만 사용할 목적으로 만들어진 메소드에 부여
// 외부에서 사용할 방법이 없음
private void print() {
System.out.println("private i: " + i);
}
// Default
void print2() {
System.out.println("default j: " + j);
}
// Protected
protected void print3() {
System.out.println("protected k: " + k);
}
// Public
public void print4() {
System.out.println("public m: " + m);
}
public static void main(String[] args) {
// Public
A a = new A();
// Private_동일 클래스에서만 접근 가능
System.out.println("=====private=====");
a.i = 100;
a.print();
// Default_동일 패키지에서만 접근 가능
System.out.println("=====default=====");
a.j = 200;
a.print2();
// Protected
System.out.println("=====protected=====");
a.k = 300;
a.print3();
// Public
System.out.println("=====public=====");
a.m = 400;
a.print4();
/*
=====private=====
private i: 100
=====default=====
default j: 200
=====protected=====
protected k: 300
=====public=====
public m: 400
*/
}
}
B.java
package j200130.test;
package j200130.test;
public class B {
public static void main(String[] args) {
// Public_같은 패키지의 다른 클래스에서 접근 가능
A a = new A();
// Private_같은 패키지에서도 클래스가 다르다면 접근 불가
System.out.println("=====private=====");
// a.i = 100; // is not visible : 접근이 불가능할 때 출력되는 에러
// a.print();
// Default_같은 패키지에서는 접근 가능
System.out.println("=====default=====");
a.j = 200;
a.print2();
// Protected_같은 패키지에서 접근 가능
System.out.println("=====protected=====");
a.k = 300;
a.print3();
// Public_같은 패키지의 다른 클래스에서 접근 가능
System.out.println("=====public=====");
a.m = 400;
a.print4();
/*
=====private=====
=====default=====
default j: 200
=====protected=====
protected k: 300
=====public=====
public m: 400
*/
}
}
j200130.test2 package
C.java
package j200130.test2;
// A 클래스가 다른 패키지에 있기 때문에 import, *을 사용하면 해당 패키지의 모든 클래스 import
import j200130.test.*;
public class C extends A {
public static void main(String[] args) {
// Public_외부 패키지의 다른 클래스에서도 접근 가능
A a = new A();
// Private_외부 클래스 및 외부 패키지에서 접근 불가
System.out.println("=====private=====");
// a.i = 10;
// a.print();
// Default_외부 패키지에서 접근 불가
System.out.println("=====default=====");
// a.j = 200;
// a.print2();
// j200130.test 패키지의 A 클래스를 상속받은 C 클래스의 인스턴스로도 접근 불가
C c = new C();
// c.j= 300;
// c.print2();
// Protected_외부 패키지에서 A 클래스로 생성한 인스턴스로는 접근 불가
System.out.println("=====protected=====");
// a.k = 300;
// a.print3();
// j200130.test.A 클래스를 상속받은 j200130.test2.C 클래스의 인스턴스로는 접근 가능
c.k = 300;
c.print3();
// Public_외부 패키지의 다른 클래스에서도 접근 가능
System.out.println("=====public=====");
a.m = 400;
a.print4();
/*
=====private=====
=====default=====
=====protected=====
protected k: 300
=====public=====
public m: 400
*/
}
}
접근 제어자는 이전에도 한 번 다룬 적이 있지만 조금 더 심화된 내용으로 상속과 함께 다루어보았습니다.
예제가 조금 길지만 패키지와 클래스간 접근제어자의 접근 가능성을 확인하기 위함이니 천천히 봐주시길 바랍니다.
접근 제어자의 범위를 정확히 알아야 상속할 때나 클레스의 멤버 변수 및 메소드에 접근할 때 헷갈리지 않기 때문에
정확히 파악해 두는 것이 좋겠습니다.