본문 바로가기

Java/기본 개념

7. 클래스와 객체 (2)

개요

'6. 클래스와 객체 (1)'에서 이어집니다.


인스턴스 멤버와 정적 멤버

클래스 멤버란, 필드와 메소드를 통틀은 말입니다.

 

인스턴스 멤버

인스턴스 멤버는 객체마다 가지고 있는 멤버를 의미합니다.

지금까지 선언한 것과 같이 인스턴스 멤버를 선언할 수 있습니다.

 

정적 멤버 static

정적 멤버는 클래스에 고정된 멤버입니다. 정적 멤버는 객체를 생성하지 않고도 사용할 수 있습니다.

정적 멤버를 선언하는 방법은 다음과 같습니다.

 

📢 출력 예시
정적 필드입니다.
정적 메소드가 호출되었습니다.

 

정적 멤버를 호출할 경우, 인스턴스 멤버와 달리 객체를 별도 생성하지 않아도 호출할 수 있습니다.

정적 멤버는 클래스 로더(Class Loader)가 바이트 코드를 로딩할 때, 클래스별로 관리되기 때문입니다.

 

상수 또는 공통된 기능을 하는 메소드와 같이 객체마다 가지고 있을 필요가 없는 공통된 데이터라면,

정적 필드로 선언하는 것이 권장됩니다.

 

정적 멤버는 객체가 아닌 클래스 그 자체에 속한 것이기 때문에,

객체 자신의 참조를 의미하는 this 키워드를 통해 호출할 수 없습니다.

 

그리고, 정적 메소드 내에서 인스턴스 변수를 사용하려면, 메소드 내에 객체를 별도로 생성하여야 합니다.

 

싱글톤

전체 프로그램에서 단 하나의 객체만의 생성을 보장해야 하는 경우가 있는데,

이 객체를 싱글톤(Singleton)이라고 부릅니다.

 

싱글톤은 클래스 외부에서 new 연산자를 통해 생성자를 호출하는 것을 막아야하므로,

생성자 앞에 private 접근 제어자를 붙입니다.

 

자신의 정적 필드를 통해 생성자를 호출하여 객체를 생성해 초기화하고, 외부 클래스에서의 접근을 막을 수 있습니다.

외부에서 호출하고 싶다면, 정적 메소드 getInstance()를 통해, 객체를 호출할 수 있습니다.

 

getInstance()는 Java에서 제공하는 예약가 아닌,

일반적으로 디자인 패턴 중 싱글톤 패턴에서 사용되는 메소드 이름일 뿐입니다.

 

📢 출력 예시
st1과 st2는 동일한 객체입니다.

 

getInstance() 메소드는 단 하나의 객체만 반환하므로, st1과 st2는 동일한 객체를 참조합니다.

 

getInstance()는 다음과 같이도 만들 수 있습니다.

 

final 필드와 상수

final 필드는 최종적인 필드라는 뜻으로,

final 필드는 초기값이 저장되면 그 값이 최종값이 되어 프로그램 실행 중 수정이 불가능해집니다.

final 필드는 처음 선언시에 초기화를 할 수 있고, 생성자를 통해 초기화할 수 있습니다.

 

또한, 앞에 static을 붙이면 상수(static final)가 되며,

이는 불변의 값임과 동시에 범용성을 띄기 때문에 static을 붙입니다.

 

상수는 이름을 모두 대문자로 작성하는 관례가 있습니다.

두 개 이상의 단어로 구성된 경우 언더바(_)를 통해 연결합니다.


패키지와 접근 제어자

패키지

패키지는 표면적으로 디렉토리(폴더)와 같은 역할을 합니다.

패키지는 클래스를 유일하게 만들어주는 기능을 하며, 이는 같은 이름의 패키지가 있더라도,

이들을 구분짓게 해주는 역할을 합니다.

 

위 클래스의 전체 이름은 WEEK01.HelloWorld가 되며,

패키지 위에 상위 패키지가 있는 경우 그 사이에 점(.)을 사용합니다.

 

사용하고자 하는 클래스가 다른 패키지에 있는 경우 import문을 이용하며,

이는 package문과 동일하게 이용할 수 있습니다.

 

클래스의 패키지를 명시하지 않은 경우, 해당 클래스는 기본 패키지(Default Package)에 소속되게 됩니다.

 

이때, ‘*’는 해당 패키지에 소속된 모든 클래스를 사용할 것임을 알리는 의미입니다.

 

접근 제어자

접근 제어자(Access Modifier)는 클래스, 필드, 메소드 등의 멤버 접근 제어를 담당합니다.

접근 제어자는 public, protected, private로 나뉘고, 이 세 개에 다 해당하지 않은 경우, default 접근 제어를 가집니다.

 

public 접근 제어자는 외부 클래스가 자유롭게 사용할 수 있도록 합니다.

protected 접근 제어자는 같은 패키지 또는 자식 클래스에서 사용할 수 있도록 합니다.

private 접근 제어자는 클래스 내부에서만 사용할 수 있도록 합니다.

default 접근 제어자는 같은 패키지에 소속된 클래스에서만 사용할 수 있도록 합니다.

 

접근 제어자의 제어 순서는 public > default > protected > private 입니다.

순서가 앞에 있을수록, 멤버 접근의 개방성이 향상됩니다.

 

📢 출력 예시
1 ↩️
두 값의 합은 0입니다.
2 ↩️
첫 번째 값을 입력해주세요: 1 ↩️
두 번째 값을 입력해주세요: 10 ↩️
1 ↩️
두 값의 합은 11입니다.
3 ↩️
프로그램을 종료합니다.

 

AccessModifier의 객체는 두 필드 input1, input2는 private이고,

두 값의 합을 구하는 메소드도 private이므로, 외부 클래스에서는 접근할 수 없습니다.

 

하지만, protected인 modifyInputs() 메소드와 public인 printResult() 메소드를 통해 private 멤버에 접근할 수 있습니다.

 

getter과 setter 메소드

객체의 필드는 객체 외부에서 직접적으로 접근하는 것을 막는 경우가 많은데,

이는 객체의 무결성*(Integrity)이 훼손될 수 있기 때문입니다.

 

예를 들어, 두 변의 길이가 주어진 직사각형의 넓이를 구하는 프로그램을 만드려고 할 때,

필드에 직접 값을 입력하게 한다면, 사용자가 음수를 넣을 수도 있습니다.

 

이때, 필드의 수정을 막는 방법은 필드를 private로, 이를 수정할 수 있는 메소드는 public으로 두는 것입니다.

이렇게 될 경우, 객체 외부에서 객체의 필드를 수정하려면 메소드를 통해 접근할 수 밖에 없게 됩니다.

 

요약하자면,

setter 메소드는 매개값을 검증해서 유효한 값만 객체의 필드에 접근할 수 있게 하는 역할을 합니다.

getter 메소드는 필드값을 가공한 후 외부로 전달하는 역할을 합니다.

 

GetterSetter 내의 필드는 모두 private이므로, 외부 클래스에서 필드의 값을 직접 수정할 수 없습니다.

수정하고 위해선 public인 setInput 메소드를 통해 객체 내의 필드값을 수정할 수 있습니다.

 

 

무결성*: 신뢰할 수 있는 서비스 제공을 위해서 의도하지 않은 요인에 의해 데이터, 소프트웨어, 시스템 등이 변경되거나 손상되지 않고 완전성, 정확성, 일관성을 유지함을 보장하는 특성.


정리

'클래스와 객체'는 객체 지향 프로그래밍의 가장 기본이 되는 개념들입니다.

다음에는 객체 지향 프로그래밍의 또 다른 특징인 '상속'을 다룹니다.

 

'Java > 기본 개념' 카테고리의 다른 글

6. 클래스와 객체 (1)  (0) 2024.05.23
5. 조건문과 반복문  (0) 2024.05.20
4. 연산자  (0) 2024.05.17
3. 변수와 자료명 (2)  (0) 2024.05.16
2. 변수와 자료명 (1)  (1) 2024.05.15