프로그래밍 도구의 기본적인 목표는 생각하는 것을 자유롭게 표현할 수 있도록 하는 것이다. 하지만 자유만으로는 부족하다. 프로그래밍은 작은 것에서 거대한 것, 단순한 것에서 복잡한 것, 단독 작업에서 협업으로 나아가게 된다. 이러한 변화를 수용하기 위해서는 다양한 규제가 필요해지게 된다. 우리 수업을 통해서 지금까지 경험한 대표적인 규제 중의 하나는 데이터 타입을 들 수 있겠다. 어떤 변수가 있을 때 그 변수에 어떤 데이터 타입이 들어있는지, 또 어떤 메소드가 어떤 데이터 타입의 데이터를 리턴하는지를 명시함으로써 사용하는 입장에서는 안심하고 변수와 메소드를 사용할 수 있게 된다. 물론 도구 설계자의 취향이나, 도구의 목적에 따라서 이러한 규제는 채택 되기도 하고, 배제 되기도 한다.
지금부터 배울 추상 클래스, final, 접근 제어자, 인터페이스 등은 바로 이 규제에 해당하는 것이다. 사려 깊은 규제라면 그것이 목적해야 하는 바는 분명해야 한다. 자유에 질서를 부여함으로서 자유를 촉진하는 것이다. 이번 시간에는 규제 중의 하나인 접근 제어자에 대해서 알아보자.
접근 제어자는 클래스의 맴버(변수와 메소드)들의 접근 권한을 지정한다
package com.yuri.javatutorials.accessmodifier;
class A {
public String y() {
return "public void y()";
}
private String z() {
return "public void z()";
}
public String x() {
return z();
}
}
public class AccessDemo1 {
public static void main(String[] args) {
A a = new A();
System.out.println(a.y());
// 아래 코드는 오류가 발생한다.
System.out.println(a.z());
System.out.println(a.x());
}
}
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
The method z() from the type A is not visible
at com.yuri.javatutorials.accessmodifier.AccessDemo1.main(AccessDemo1.java:22)
메소드가 키워드 private으로 시작되고 있다. private은 클래스(A) 밖에서는 접근 할 수 없다는 의미다. 바로 이 private의 자리에 오는 것들을 접근 제어자(access modifier)라고 한다.
package com.yuri.javatutorials.accessmodifier;
class Calculator {
private int left, right;
public void setOprands(int left, int right) {
this.left = left;
this.right = right;
}
private int _sum() {
return this.left + this.right;
}
public void sumDecoPlus() {
System.out.println("++++" + _sum() + "++++");
}
public void sumDecoMinus() {
System.out.println("----" + _sum() + "----");
}
}
public class CalculatorDemo {
public static void main(String[] args) {
Calculator c1 = new Calculator();
c1.setOprands(10, 20);
c1.sumDecoPlus();
c1.sumDecoMinus();
}
}
/*
++++30++++
----30----
*/
이 두개의 변수는 객체 외부에서 호출될 필요가 없다. 따라서 외부로부터 이 변수를 숨기기 위해서 접근 제어자로 private을 지정했다.
또한 메소드 _sum이 추가 되었는데 실제 계산은 이 메소드가 내부적으로 처리하고, 계산된 결과를 외부에 출력해주는 메소드는 sumDecoPlus, sumDecoMinus에서 처리한다.
이상과 같은 조치를 통해서 사용자가 접근하면 안되거나 접근 할 필요가 없는 맴버에 대한 접근을 규제할 수 있게 되었다. 어떤 맴버에 대한 접근을 허용할 것인가를 작업자의 판단에 달렸다.
접근 제어자는 public과 private외에도 두가지가 더 있다. protected과 default가 그것이다. protected는 상속 관계에 있다면 서로 다른 패키지에 있는 클래스의 접근도 허용한다. default는 접근 제어 지시자가 없는 경우를 의미하는데, 접근 제어자가 없는 메소드는 같은 패키지에 있고 상속 관계에 있는 메소드에 대해서만 접근을 허용한다. 아래 그림은 접근 제어자 별로 접근의 허용범위를 그림으로 나타낸 것이다. 안쪽에 있을수록 접근 통제가 삼엄하고, 밖에 있을수록 접근이 허용된다. (
지금까지는 클래스 맴버에 대한 접근 제어자를 살펴봤다. 이번에 살펴볼 것은 클래스의 접근 제어자다. 클래스도 접근 제어자가 있다. 클래스의 접근 제어자는 총 2개로 public과 default이다. default는 접근 제어자를 붙이지 않은 경우 default가 된다. 클래스의 접근 제어자는 패키지와 관련된 개념이다. 즉 접근 제어자가 public인 클래스는 다른 패키지의 클래스에서도 사용할 수 있고, default인 경우는 같은 패키지에서만 사용 가능하다.
두개의 클래스를 만들자
package com.yuri.javatutorials.accessmodifier.inner;
public class PublicClass {
}
package com.yuri.javatutorials.accessmodifier.inner;
class DefaultClass {
}
위의 클래스들과 같은 패키지에서 이 클래스들을 사용한 결과 오류가 발생하지 않는다.
package com.yuri.javatutorials.accessmodifier.inner;
public class ClassAccessModifierInnerPackage {
PublicClass publicClass = new PublicClass();
DefaultClass defaultClass = new DefaultClass();
}
이번에는 다른 패키지에 있는 클래스에서 사용해보자.
package com.yuri.javatutorials.accessmodifier.outter;
import com.yuri.javatutorials.accessmodifier.inner.*;
public class ClassAccessModifierOuterPackage {
PublicClass publicClass = new PublicClass();
// DefaultClass defaultClass = new DefaultClass();
// 오류 발생! DefaultClass의 접근 제어자가 default이기 때문이다.
}
주석으로 처리한 부분은 오류가 발생한다. DefaultClass의 접근 제어자가 default이기 때문 😐
package com.yuri.javatutorials.accessmodifier.inner;
// public class PublicName {}
// public 클래스가 포함된 소소코드는 public 클래스의 클래스 명과 소스코드의 파일명이 같아야 한다
public class PublicNameDemo {}
한가지 중요한 제약 사항이 있다. public 클래스가 포함된 소소코드는 public 클래스의 클래스 명과 소스코드의 파일명이 같아야 한다. 위 코드의 이름은 PublicNameDemo.java이다. 주석처리된 부분은 오류가 발생한다. 퍼블릭 클래스의 이름과 소스코드의 이름이 일치하지 않기 때문이다. 그 말은 하나의 소스 코드에는 하나의 public 클래스가 존재 할 수 있다는 의미다.
접근 제어자는 그것이 무엇인지, 또 어떤 접근 제어자가 있는지 정도만 일단 알아두자. 그리고 당분간은 public과 private만 구분해서 사용만해도 더 안전하고 결고한 에플리케이션을 만들 수 있을 것 😀
이 글은 생활코딩의 자바 강좌를 바탕으로 정리한 내용입니다.