🔐 정보은닉(Informaiton hiding)
- 정보은닉 : 다른 객체에게 자신의 정보를 숨기고 자신의 동작, 기능, 연산만을 통해 접근을 허용하는 것으로, 클래스 외부에서 특정 정보에 접근을 막는다는 의미이다. 캡슐화와 연관성이 밀접한 단어이다.
- 캡슐화 : 정보 은닉은 객체의 속성과 메서드를 적절하게 그룹화하여 외부에 노출시키지 않습니다. 객체 내부의 구현 세부 사항은 외부로부터 숨겨지고, 오직 공개된 인터페이스만을 통해 상호작용할 수 있습니다. 이를 통해 객체는 자신의 상태와 동작을 캡슐화하고, 외부에서는 그 구체적인 내용을 알 필요 없이 사용할 수 있습니다.
💡 정보은닉이 되어있는 상태정보에 접근하는 방법 (private에 접근하는 방법) 2가지의 대표 방법이 있다.
데이터에 쉽게 접근하지 못하게 상태정보를 private로 설정해두었다면, 해당 데이터를 메인 클래스에서
객체를 생성하여 사용하지 못하게 됩니다. ( private는 자기자신을 제외 모든 패키지에서 접근이 불가하기 때문입니다.)
1. Getter와 Setter
객체 지향 프로그래밍에서 클래스의 속성(=상태정보) 에 접근하고 값을 가져오거나 설정하기 위한 메서드를 말합니다.
일반적으로 속성은 private으로 선언되어 외부에서 직접 접근할 수 없으므로, Getter와 Setter를 사용하여 간접적으로 필드에 접근하고 값을 가져오거나 설정합니다.
< Getter와 Setter의 예시 >
< Getter와 Setter의 예시 >
public class Person {
private String name; // private 필드
public String getName() { // Getter 메서드
return name;
}
public void setName(String newName) { // Setter 메서드
name = newName;
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person();
person.setName("John"); // Setter를 통해 필드 값 설정
String name = person.getName(); // Getter를 통해 필드 값 읽기
System.out.println(name); // 출력: John
}
}
🎈 Getter는 속성의 값을 반환하는 메서드로, 외부에서 속성 값을 읽을 수 있도록 합니다.
Getter는 일반적으로 속성 이름 앞에 "get" 접두사를 붙이고, 속성의 데이터 타입과 일치하는 값을 반환합니다.
밖으로 데이터를 보내주는 용도 get멤버변수(이 때, 멤버변수의 시작은 대문자로 시작한다)
🎈 Setter는 속성에 값을 설정하는 메서드로, 외부에서 속성 값을 변경할 수 있도록 합니다.
Setter는 일반적으로 속성 이름 앞에 "set" 접두사를 붙이고, 속성의 데이터 타입과 일치하는 매개변수를 받아 필드 값을 변경합니다.
저장하는 용도 set멤버변수(이 때, 멤버변수의 시작은 대문자로 시작한다) → 메서드로서 매개변수로 name이라는 변수를 받아,
this로 접근하여 받아온 name을 값을 this.name(클래스가 가지고 있는 멤버변수)에다가 할당해준다.
💡 Getter와 Setter의 주요 목적은 정보 은닉(Encapsulation)을 유지하면서 속성에 접근하는 기능을 제공하는 것
입니다. 속성을 private으로 선언하여 직접 접근을 제한하고, Getter와 Setter를 통해 필드에 접근하면서 캡슐화를 유지할 수 있습니다.
private로 접근이 제한된 변수들을 get,set을 사용하여 public으로 외부 클래스에서도 접근이 가능할 수 있게 설정해주었습니다.
set속성으로 해당 메모리공간을 불러온 후 ( )안에 출력되기를 원하는 데이터를 입력한 후, get속성으로 출력할 수 있습니다.
2. 생성자 메서드를 통해서 접근 가능(객체 초기화)
- 생성자 메서드를 아무것도 만들지 않으면 컴파일러가 자동으로 default 생성자가 생성되어 있는데 그 default 생성자 안에 this.속성(상태정보) = “데이터”; 와 같은 문법으로 객체를 생성한 후 초기화를 하여 정보은닉화 된 메모리 공간에 값을 저장해 줄 수 있습니다.
- 생성자 메서드의 역할은 객체를 생성한 후, 객체가 가지고 있는 상태정보에 데이터를 바로 저장할 때 생성자 메서드를 사용하게됩니다.
- private 접근 제한자는 같은 클래스 내에서는 자기자신의 데이터로 접근이 허용되고 생성자 메서드 내부에서 this를 이용해메모리공간에 값을 입력하는 것이 가능합니다.
setter 대신 생성자를 초기화하여 속성 값에 데이터를 입력해주면 setter는 작성할 필요없이 getter로 main메서드에서 호출하여 사용하면 된다.
public class Person {
private String name;
private int age;
// 생성자 초기화
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getter 메서드
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class Main {
public static void main(String[] args) {
// 생성자를 통해 객체 생성 및 초기화
Person person = new Person("John", 25);
System.out.println(person.getName()); // 출력: John
System.out.println(person.getAge(); // 출력: 25
}
}
3. 생성자 메서드를 오버로딩(Overloading)해서 초기화 가능
PersonVO p = new PersonVO(”홍길동”, 50, “010-1234-4567”); 위와 같이 작성하여 객체를 생성함과 동시에 p에 값들을 입력해주고, 해당 값들을 class PersonVO에 생성자 메서드를 오버로딩하여 초기화가 가능하다.
public PersonVO(String name, int age, String phone) {
this.name = name;
this.age = age;
this.phone = phone;
}
PersonVo class
//생략된 생성자 메서드가 있다. -> 기본생성자 (default Constructor)
public PersonVo() {
this.name = "홍길동";
this.age = 30;
this.phone = "111-1111-1111";
}
public PersonVo(String name, int age, String phone) {
//객체를 생성하는 코드는 내부에서 만들어진다.
//객체를 초기화 한다.
this.name = name;
this.age = age;
this.phone = phone;
}
import model.PersonVo;
public class Capsul_personvo {
public static void main(String[] args) {
//Q. 한사람의 [회원] 정보를 저장할 [객체를 생성]하세요.
PersonVo vo = new PersonVo();
PersonVo vo1 = new PersonVo("나길동" , 50, "222-2222-2222");
PersonVo vo2 = new PersonVo("나길동" , 50, "222-2222-2222");
System.out.println(vo.getName() + "\t" + vo.getPhone() + "\t" + vo.getAge());
System.out.println(vo1.getName() + "\t" + vo1.getPhone() + "\t" + vo1.getAge());
System.out.println(vo2.getName() + "\t" + vo2.getPhone() + "\t" + vo2.getAge());
}
}
🎈 toString() 메서드를 활용하여 객체가 가지고 있는 모든 값을 리턴하기
생성자 메서드를 활용하여 개발자가 입력한 데이터를 입력하여 객체를 출력할 수 있게는 하였지만, getter를 각각의 속성들 마다 입력하여 불러오는 번거로움이 발생합니다.
이 때, toString() 메서드를 활용하면 객체 내부에 저장된 모든 값들을 한번에 문자열로 출력할 수 있게됩니다. 그럼 getter를 하나하나 입력하는 것이 아닌, toString 메서드에 만들어진 retrun 값대로 출력할 수 있게됩니다.
public String toString() {
return name + "\t"+age+"\t"+phone;
}
import model.PersonVo;
public class ToStringPrint {
public static void main(String[] args) {
//Q.생성자 메서드를 통해서 PersonVo객체에 원하는 이름, 나이, 전화번호를 저장하고 toString() 메서드로 출력하세요.
PersonVo vo = new PersonVo("홍길동" , 34, "111-1111-1111");
System.out.println(vo.getName() + "\t" + vo.getAge()+"\t"+vo.getPhone());
System.out.println(vo.toString());
//getter를 세번이나 입력해서 출력을 반복하는 것보다 toString
System.out.println(vo); -> vo.toString() 과 동일한 출
}
}
여기서 toString의 생략도 가능해진다. 생성자 메서드로 저장된 vo객체만 입력하여 출력했다고 하더라도, 컴파일러가 객체가 가지고 있는
모든 데이터를 출력해야한다고 판단하여, vo.toString이라는 메서드를 찾아서 toString 메서드에 의해서 출력될 수 있도록 진행해준다.
💡 잘 설계된 VO 클래스란 ?
1. 모든 상태정보 ( = 속성)을 정보 은닉하기 (private)
2. default 생성자를 반드시 만들기
3. 생성자 메서드를 오버로딩하여 객체 초기화 하기
4. setter 메서드를 만들기( 값을 저장하기 위한 용도)
5. getter 메서드를 만들기( 값을 가져오기위한 용도)
6. toString() 메서드를 만들기( 객체가 가지고 있는 전체 값 출력 용도)
💡 intelliJ에서 제공하는 Generate 이용하기
먼저 VO파일을 생성한 후 우클릭을 누르면 Generate라는 메뉴가 보이는데 해당 메뉴를 이용하여 default 생성자 및 getter setter를 손쉽게 생성할 수 있다.
Constructor를 클릭하여 default생성자 및 만들어진 기본 생성자를 오버로딩하는 메서드도 만들 수 있고, Getter and Setter를 클릭하면 선언된 속성에 따르는 getter setter를 바로 만들 수 있다.
'[ BACKEND] > JAVA_객체지향' 카테고리의 다른 글
[JAVA] 객체 생성 & Static 과의 관계 (0) | 2023.06.16 |
---|---|
[JAVA] static과 JVM의 메모리 모델 (0) | 2023.06.15 |
[JAVA] 객체 접근 권한 & 패키지 (1) | 2023.06.13 |
[JAVA] 클래스(모델)의 종류 (1) | 2023.06.12 |
[JAVA] 클래스로 객체 모델링 (0) | 2023.06.11 |