Java Class Notes

Access Modifier and Encapsulation (접근제어자와 캡슐화)

헤일리유 2023. 2. 23. 16:02

 

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)

 

 

 

 

 

 

 

캡슐화의 장점

 

객체에 포함된 정보의 손상과 오용을 막을 수 있다.

객체 조작 방법이 바뀌어도 사용방법은 바뀌지 않는다. 데이터가 바뀌어도 다른 객체에 영향을 주지 않아 독립성이

유지된다.
처리된 결과만 사용하므로 객체의 이식성이 좋다. 객체를 부품화 할 수 있어 새로운 시스템의 구성에

부품처럼 사용할 수 있다.

 

 

 

 

 

 

 

 

 

 

캡슐화 하는 법

  1. 메소드나 필드 앞에 private라는 접근제어자를 사용 private int age=25;
    private String name="Jin Sil";
    private String addr="Korea";
  2. 캡슐화된 객체의 필드값을 읽거나 변경하기 위해 사용하는 메소드들을 접근자 메소드 또는 인터페이스 메소드라고 한다. 외부접근자가 사용할수 있는 필드나 메소드 앞에 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