Access Modifier 접근제어자
접근제어자란?
멤버 또는 클래스에 사용되어 외부로부터의 접근을 제한한다.
접근제어자가 사용될 수 있는 곳
- 클래스, 멤버변수, 메서드, 생성자
접근제어자 종류
private - 같은 클래스 내에서 접근 가능
default - 같은 패키지 내에서 접근 가능
protected - 같은 패키지 내에서 그리고 다른 패키지의 자손 클래스에서 접근 가능
public - 접근 제한이 전혀 없다.
제어자 | Same Class | Same Package | 자손 클래스 | 전체 |
public | O | O | O | O |
protected | O | O | O | |
default | O | O | ||
private | O |
Example - private access modifier
package ch06;
public class Person {
private String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age<0) {
System.out.println("Age can't be smaller than 0");
this.age = 0;
} else this.age = age;
}
}
package ch06;
public class PersonEx {
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("Hani");
System.out.println("Name : "+p1.getName());
p1.setAge(-12);
System.out.println("Age : "+p1.getAge());
}
}
private 이 붙어있는 정보는 바로 접근할 수가 없기 때문에 메소드를 통해서 접근할 수 있다.
(메소드를 통해 접근하는 것이 안전하다.)
Eclipse
Source > Generate Getters and Setters
만들고 싶은 항목 앞에 체크 하고 generate 누르기
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
그럼 이렇게 두가지가 생긴다.
후에 조금 더 수정한 코드
package ch06;
public class Person {
private String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age<0) {
System.out.println("Age can't be smaller than 0");
this.age = 0;
} else this.age = age;
}
void print() {
System.out.println("===================");
System.out.println("Name : "+name);
System.out.println("Age : "+age);
}
}
package ch06;
public class PersonEx {
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("Hani");
p1.setAge(12);
p1.print();
Person p2 = new Person();
p2.setName("Rose");
p2.setAge(26);
p2.print();
Person p3 = new Person();
p3.setName("Bunnie");
p3.setAge(29);
p3.print();
}
}
result :
===================
Name : Hani
Age : 12
===================
Name : Rose
Age : 26
===================
Name : Bunnie
Age : 29
접근제어자를 사용하는 이유
- 외부로부터 데이터를 보호하기 위해서
-외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
>> 접근제어자를 통한 캡슐화
생성자의 접근제어자
- 일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치한다.
- 생성자에 접근 제어자를 사용함으로써 인스턴스의 생성을 제한할 수 있다.
Sigleton
EX 1
package ch06;
// Singleton, Design Pattern
public class Single1 {
// static 붙으면 클래슷 로딩할 때 1번 실행 클래스변수
private static Single1 instance = new Single1();
// private을 사용하면 외부에서 객체를 생성 못함
private Single1() {}
// 처음에 생선된 instance를 같이 사용
// 객체를 생성할 때는 instance를 사용
public static Single1 getInstance() {
return instance;
}
}
package ch06;
public class Single1Ex {
public static void main(String[] args) {
Single1 s1 = Single1.getInstance();
Single1 s2 = Single1.getInstance();
if (s1 == s2)System.out.println("same");
else System.out.println("different");
System.out.println(s1);
System.out.println(s2);
}
}
result :
same
ch06.Single1@5674cd4d
ch06.Single1@5674cd4d
EX 2
package ch06;
// Singleton, Design Pattern
public class Single1 {
// static 붙으면 클래슷 로딩할 때 1번 실행 클래스변수
private static Single1 instance = new Single1();
// private을 사용하면 외부에서 객체를 생성 못함
Single1() {}
// 처음에 생선된 instance를 같이 사용
// 객체를 생성할 때는 instance를 사용
public static Single1 getInstance() {
return instance;
}
}
package ch06;
public class Single1Ex {
public static void main(String[] args) {
// 객체를 출력 패키지명.클래스명@해시코드
// packagename.classname@hashcode
Single1 p1 = new Single1();
Single1 p2 = new Single1();
Single1 p3 = new Single1();
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
Single1 s1 = Single1.getInstance();
Single1 s2 = Single1.getInstance();
Single1 s3 = Single1.getInstance();
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}
}
result :
ch06.Single1@5674cd4d
ch06.Single1@63961c42
ch06.Single1@65b54208
ch06.Single1@1be6f5c3
ch06.Single1@1be6f5c3
ch06.Single1@1be6f5c3
제어자의 조합
1. 메서드에 static과 abstract를 함께 사용할 수 없다.
- static메서드는 몸통(구현부)이 있는 메서드에만 사용할 수 있기 때문이다.
2. 클래스에 abstract와 final을 동시에 사용할 수 없다.
- 클래스에 사용되는 final은 클래스를 확장할 수 없다는 의미이고, abstract는 상속을 통해서 완성되어야
한다는 의미이므로 서로 모순되기 때문이다.
3. abstract메서드의 접근제어자가 private일 수 없다.
- abstract메서드는 자손클래스에서 구현해주어야 하는데 접근 제어자가 private이면, 자손클래스에서
접근할 수 없기 때문이다.
4. 메서드에 private과 final을 같이 사용할 필요는 없다.
- 접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문이다. 이 둘 중 하나만 사용해도 의미가 충분하다.
캡슐화 (Encapsulation)
다른 객체의 필드(멤버변수)값을 직접 읽거나 수정할 수 없게 하고 반드시 별도의 메소드를 통하도록 속성과 메소드를 결합시키는 행위를 객체 지향 방법론에서는 캡슐화라고 한다.
캡슐화의 최대 목적은 정보은닉이라고 볼 수 있다.
캡슐화
- 객체를 캡슐화 하여 자기만 보여주고 user에게는 감춘다.
- 객체를 작성할 때 숨겨야 하는 정보(private)와 공개해야 하는 정보(public)를 구분하여 작성
- 객체의 사용자는 기능만 알고 사용하며 어떻게 처리되는지는 은폐된다(Information Hiding)
캡슐화의 장점
객체에 포함된 정보의 손상과 오용을 막을 수 있다.
객체 조작 방법이 바뀌어도 사용방법은 바뀌지 않는다. 데이터가 바뀌어도 다른 객체에 영향을 주지 않아 독립성이
유지된다.
처리된 결과만 사용하므로 객체의 이식성이 좋다. 객체를 부품화 할 수 있어 새로운 시스템의 구성에
부품처럼 사용할 수 있다.
캡슐화 하는 법
- 메소드나 필드 앞에 private라는 접근제어자를 사용 private int age=25;
private String name="Jin Sil";
private String addr="Korea"; - 캡슐화된 객체의 필드값을 읽거나 변경하기 위해 사용하는 메소드들을 접근자 메소드 또는 인터페이스 메소드라고 한다. 외부접근자가 사용할수 있는 필드나 메소드 앞에 public사용하여 접근자 메소드를 추가한다.
public void setAge(int age){
this.age=age; set => 값을 세팅
}
public int getAge(){ return age; get => 값을 얻어 온다,돌려준다
}
EX
package ch06;
// Singleton, Design Pattern
public class Single1 {
// static 붙으면 클래슷 로딩할 때 1번 실행 클래스변수
private static Single1 instance = new Single1();
// private을 사용하면 외부에서 객체를 생성 못함
private Single1() {}
// 처음에 생선된 instance를 같이 사용
// 객체를 생성할 때는 instance를 사용
public static Single1 getInstance() {
return instance;
}
}
package ch06;
public class Single1Ex {
public static void main(String[] args) {
Single1 s1 = Single1.getInstance();
Single1 s2 = Single1.getInstance();
if (s1 == s2)System.out.println("same");
else System.out.println("different");
System.out.println(s1);
System.out.println(s2);
}
}
result :
same
ch06.Single1@5674cd4d
ch06.Single1@5674cd4d
'Java Class Notes' 카테고리의 다른 글
Inner Class(내부 클래스) (0) | 2023.02.24 |
---|---|
Inheritance(상속) (0) | 2023.02.24 |
Ex - OOP (0) | 2023.02.23 |
Method (메소드) (0) | 2023.02.23 |
Ex - Array (0) | 2023.02.22 |