1. 접근 지정자
오늘은 자바의 접근 지정자에 대해서 배워보려 합니다. 접근 지정자는 그대로 클래스 내에서 멤버의 접근을 제한하는 역할을 합니다. 우리가 오늘 배울 접근 지정자에는 private, public, protected, default가 있습니다.
우선 private, public, protected, default가 각각 무엇인지 간략히 보고 바로 예제를 봅시다.
● public : 모든 접근을 허용합니다. 어떠한 클래스가 접근을 하든 모두 허용됩니다.
● protected : 상속받은 클래스 또는 같은 패키지에서만 접근이 가능합니다.
● default : 기본 제한자로써 아무것도 붙지 않고, 자신 클래스 내부와 같은 패키지 내에서만 접근이 가능.
● private : 외부에서 접근이 불가능합니다. 즉, 같은 클래스 내에서만 접근이 가능합니다.
아래의 표를 보시면 쉽게 이해하실 수 있습니다.
한정자 |
클래스 내부 |
동일 패키지 |
하위 클래스 |
그 외의 영역 |
public |
● |
● |
● |
● |
protected |
● |
● |
● |
X |
default |
● |
● |
X |
X |
private |
● |
X |
X |
X |
접근 영역: public > protected > default > private
(여기서 패키지(package)란 사전적 의미 그대로 '상자, 포장물'을 의미합니다. 관련된 클래스 혹은 인터페이스들을 묶어놓은 상자와 같습니다. 이번 강좌에서는 패키지가 대충 이렇다 한것만 알아두고 나중에 패키지를 다시한번 설명하도록 하겠습니다.)
Private:
아래의 예제는 private 지시자를 사용하여 그 멤버에 접근하는 예제입니다.
class A {
private int data = 40;
private void msg() { System.out.println("Hello java"); }
}
class Simple {
public static void main(String args[]) {
A obj = new A();
System.out.println(obj.data);
obj.msg();
}
}
다음을 컴파일 해봅시다. 컴파일 하자마자 갑자기 에러가 발생합니다.
Simple.java:11: error: data has private access in A
System.out.println(obj.data);
^
Simple.java:12: error: msg() has private access in A
obj.msg();
^
2 errors
왜 에러가 나신지 아실겁니다. 위에서 말씀드렸듯이, private 지시자를 사용하면 해당 멤버는 외부에서 접근이 불가능하다 했습니다. 오로지 클래스 내에서만 접근이 가능하죠. 그래서 에러가 발생했던겁니다.
Default:
이제는, default를 볼까요? 이 기본(default) 제한자는 아무것도 적지 않아도 됩니다.
class A {
int data = 40;
void msg() { System.out.println("Hello java"); }
}
class Simple {
public static void main(String args[]) {
A obj = new A();
System.out.println(obj.data);
obj.msg();
}
}
결과:
40
Hello java
그렇다면 다른 패키지에서의 접근은 어떻게 될까요? 우선 아직은 패키지를 배우지 않았으므로, 과정을 설명드리도록 하겠습니다.
A.java 코드:
package com.pack; // com 폴더 내에 pack란 하위 디렉토리를 만들고 거기에 A.class를 저장
public class A {
void msg() { System.out.println("Hello"); }
}
B.java 코드:
import com.pack.A; // com 폴더 내의 pack란 하위 디렉토리에 존재하는 A 클래스를 사용
class B {
public static void main(String args[]) {
A obj = new A();
obj.msg();
}
}
A.java 컴파일 시:
javac -d . A.java
A.java를 컴파일 하고 B.java를 컴파일 하는 순간 또 에러가 발생했습니다.
B.java:7: error: msg() is not public in A; cannot be accessed from outside packa
ge
obj.msg();
^
1 error
A 클래스 내에 있는 msg라는 메소드가 public이 아니여서 외부에서 접근을 못한다는 겁니다. 이것 역시, default는 동일 패키지 내에서는 접근이 가능하지만 외부에서는 접근이 불가능 하다는것을 기억하고 계셔야 합니다. 다음은 protected 지시자에 대한 예제입니다.
Protected:
외부에서 접근은 불가능하나 동일 패키지, 상속받은 클래스에선 접근이 가능합니다.
class A {
protected int num;
...
}
class B extends A {
protected int num;
public init(int n) {
num = n;
}
...
}
Protected에서 상속의 개념이 빠지면 default라고 생각하시면 됩니다.
Public:
public은 모든 영역에서 접근이 가능하죠.
class Circle
{
public float pi=3.141f,radius,area;
public void area()
{
area = pi*radius;
System.out.println("원의 넓이 : "+area);
}
}
public class PublicAccessModifier {
public static void main(String args[])
{
Circle c = new Circle();
c.radius = 8.19f;
c.area();
}
}
결과:
원의 넓이 : 25.724789
접근 지정자에 대한 강좌는 여기에서 그만 마치도록 하겠습니다. 이해가 잘 안되시거나 설명이 좀 부족하다 싶으면 댓글을 달아주시면 보충 설명을 달아드리도록 하겠습니다. 수고하셨습니다.
다음 강좌에서는 패키지(package)에 대해서 공부합니다.
'프로그래밍 관련 > 자바/자바 스크립트' 카테고리의 다른 글
JAVA 강좌 20편. 추상 클래스(Abstract Class) (5) | 2012.08.21 |
---|---|
JAVA 강좌 19편. 패키지(Package) (8) | 2012.08.21 |
JAVA 강좌 18편. 접근 지정자(Access Modifiers) (14) | 2012.08.19 |
JAVA 강좌 17편. 상속(Inheritance) (20) | 2012.08.16 |
JAVA 강좌 16편. 배열을 매개변수로 받는 메소드, 다차원 배열 (11) | 2012.08.13 |
JAVA 강좌 15편. 배열(Array) (18) | 2012.08.12 |
질문이 있습니다. C++같은 경우 Class를 생성할때,
private:
int a;
int b;
public:
....
이런식으로 매번 private, public을 적어줄 필요가 없는데. Java에서는 이런식으로 표현이 안되는건가요?
적어주신 예제를 보면 항상 변수나 메소드를 선언하실때 private, public을 계속 붙여서 적어주시고 계시던데...
package com.pack; // com 폴더 내에 pack란 하위 디렉토리를 만들고 거기에 A.class를 저장<=a.java 컴파일시 디렉토리는 생성이 안되고 a.java가 있는 폴더에 그대로 컴파일링 되는데 왜 디렉토리가안만들어지죠?ㅠㅠ
public class A {
void msg() { System.out.println("Hello"); }
}
아 되네요ㅠㅠ
javac -d . A.java<=컴파일시 이 부분 -d 는 옵션같던데 무얼뜻하는거에여?
감사합니다~
안녕하세요. 강좌 정말 유용하게 잘 보고 있습니다. 먼저 감사드리고요.
그런데 질문이 하나 있습니다.
접근지정자에서 "같은 패키지 내에서만 접근이 가능하다" 라는 뜻을 이해를 못하겠는데요.
예를 들어서 패키지가 들어있는 폴더가 java.utill 이라면
java.util 밑에 있는 A.class 와 B.class 가 들어있습니다.
그러면 A.class 에 있는 변수(Default 혹은 Protected 변수) 를 B.class 에서 접근 가능하다는 뜻인가요?
아니면 같은 패키지라는것이 A.class 안에 선언되어있는 둘 이상의 class 들을 말하는것인지요?
java.chater1 패키지에 a.class를 만들고
기본 패키지에 ch.java를 생성해서 ch.java에서 a.class를 임포트 시키고
메인 메소드에서
a a1 = new a(); 이렇게 하고
a1.test(); <-여기서 test()는 a클래스안에 있는 public void test()임
했는데
Exception in thread "main" java.lang.SecurityException: Prohibited package name: java.chapter1
at java.lang.ClassLoader.preDefineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$100(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at ch1.main(ch1.java:20)
이렇게 뜨네요 이거 뭐가 잘못된거죠
핵심만 꼭 집어서 정리 잘 하셧네요. 모르던 부분 잘 이했습니다. 감사해요 ^^