6.9 인스턴스 맴버와 this
- 객체(인스턴스) 마다 가지고 있는 필드와 메소드
• 이들을 각각 인스턴스 필드, 인스턴스 메소드라고 부름
- 인스턴스 멤버는 객체 소속된 멤버이기 때문에 객체가 없이 사용불가
인스턴스(instance) 맴버란 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드를 말하는데, 이들은 각각 인스턴스 필드, 인스턴스 메소드라고 부른다.
인스턴스 필드와 메소드는 객체에 소속된 멤버이기 때문에 객체 없이는 사용할 수 없다.
Car 클래스에 gas 필드와 setSpeed() 메소드가 다음과 같이 선언되어 있다고 가정해보자.
public class Car{
// 필드
int gas;
//메소드
void setSpeed(int speed){
}
}
gas필드와 setSpeed() 메소드는 인스턴스 멤버이기 때문에 외부 클래스에서 사용하기 위해서는 우선 Car 객체(인스턴스)를 생성하고 참조변수 myCar로 접근해야 한다.
Car mycar = new Car();
myCar.gas = 10;
myCar.setSpeed(60);
객체 외부에서 인스턴스 멤버에 접근하기 위해 참조 변수를 사용하는 것고 ㅏ마찬가지로 객체 내부에서도 인스턴스 맴버에 접근하기위해 this를 사용할 수 있다.
this.model은 자신이 가지고 있는 model 필드라는 것이다.
this는 주로 생성자와 메소드의 매개 변수 이름이 필드와 동일한 경우, 인스턴스 맴버인 필드임을 명시하고자 할 때 사용된다.
Car(String model){
this.model = model;
}
void setModel(String model){
this.model = model;
}
6.10 정적 멤버와 static
- 클래스에 고정된 필드와 메소드 - 정적 필드, 정적 메소드
- 정적 멤버는 클래스에 소속된 멤버
• 객체 내부에 존재하지 않고, 메소드 영역에 존재
• 정적 멤버는 객체를 생성하지 않고 클래스로 바로 접근해 사용
정적(static)은 "고정된" 이라는 의미를 가지고 있다.
정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다.
6.10.1 정적 맴버 선언
정적 필드와 메소드를 선언하는 방법은 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 된다.
정적 필드와 메소드는 클래스에 고정된 멤버이므로 클래스 로더가 클래스를 로딩해서 메소드 메모리 영역에 적재할 때 클래스별로 관리된다. 따라서 클래스 로딩이 끝나면 사용할 수 있다.
6.10.2 정적 멤버 사용
클래스가 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있는데, 클래스 이름과 함께 도트( . ) 연산자로 접근한다.
다음과 같이 Calculator 클래스가 작성 되어 있다고 가정하면
public class Calculator{
static double pi = 3.14195;
static int plus(int x, int y){....}
static int minus(int x, int y){....}
}
정적 필드 pi와 정적 메소드 plus(), minus는 아래와 같이 사용할 수 있다.
double result1 = 10 * 10 * Calculator.pi;
int result2 = Claculator.plus(10,5);
int result2 = Claculator.minus(10,5);
정적 필드와 메소드는 원칙적으로는 클래스 이름으로 접근해야 하지만 다음과 같이 객체 참조 변수로도 접근이 가능하다.
6.10.3 정적 초기화 블록
정적 필드는 선언과 동시에 초기값을 주는 것이 보통이다.
static double pi = 3.14159;
그러나 계산이 필요한 초기 작업이 있을 수 있다.
인스턴스 필드는 생성자에서 초기화 하지만, 정적 필드느 ㄴ개겣 생성 없이도 사용해야 하므로 생성자에서 초기화 작업을 할 수 없다.
생성자는 객체생성 시에만 실행되기 때문이다.
그럼 초기화 작업을 어디서 해야 할까?
자바는 정적 필드 초기화를 위해 정적 블록을 제공한다.
정적 블록은 클래스가 메모리로 로딩될 떄 자동적으로 실행된다.
정적 블록은 클래스 내부에 여러개가 선언 되어도 상관없다.
클래스가 메모리로 로딩될 때 선언된 순서대로 실행된다.
public class Television{
static String company = "samsung";
static String model = "LCD";
static String info;
static{
info = company + model;
}
}
info 필드에는 company변수와 model 변수가 연결된 samsungLCD가 저장된다.
6.10.4 정적 메소드와 블록 선언시 주의점
- 객체가 없어도 실행 가능
- 블록 내부에 인스턴스 필드나 인스턴스 메소드 사용 불가
- 객체 자신의 참조인 this 사용 불가
• EX) main()
6.10.5 싱글톤(Singleton)
- 하나의 애플리케이션 내에서 단 하나만 생성되는 객체
가끔 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있다.단 하나만 생성된다고 해서 싱글톤이라고 한다.
싱글톤을 만들려면 클래스 외부에서 new 연산자로 생성자를 호출 할 수 없도록 막아야 한다.생성자를 호출한 만큼 객체가 생성되기 때문이다.
public class 클래스{
//정적필드
private static 클래스 singleton = new 클래스();
//생성자
private 클래스(){ }
//정적 메소드
static 클래스 getInstance(){
return singleton;
}
}
외부에서 객체를 얻는 유일한 방법은 getInstance() 메소드를 호출하는 방법이다.getInstance() 메소드는 단 하나의 객체만 리턴하기 때문에 아래 코드에서 변수1과 변수2는 동일한 객체를 참조한다.
클래스 변수1 = 클래스.getInstance();
클래스 변수2 = 클래스.getInstance();
6.11 final 필드와 상수
6.11.1 final 필드
- 최종적인 값을 갖고 있는 필드 = 값을 변경할 수 없는 필드
- final 필드의 딱 한번의 초기값 지정 방법
• 필드 선언 시
• 생성자
6.11.2 상수(static final)
- 상수 = 정적 final 필드
• final 필드:
- 객체마다 가지는 불변의 인스턴스 필드
• 상수(static final):
- 객체마다 가지고 있지 않음
- 메소드 영역에 클래스 별 로 관리되는 불변의 정적 필드
- 공용 데이터로서 사용
- 상수 이름은 전부 대문자로 작성
- 다른 단어가 결합되면 _ 로 연결
정적 블록에서도 초기화가 가능하다.
static final 타입 상수 [= 초기값];
static final 타입 상수;
static{
상수 = 초기값;
}
6.12 패키지
프로잭트를 개발하다 보면 적게는 수십 개, 많게는 수백개의 클래스를 작성해야 한다.
클래스를 체계적으로 관리하기 위해 패키지(package)를 사용한다.
- 클래스를 기능별로 묶어서 그룹 이름을 붙여 놓은 것
• 파일들을 관리하기 위해 사용하는 폴더(디렉토리)와 비슷한 개념
• 패키지의 물리적인 형태는 파일 시스템의 폴더
- 클래스 이름의 일부
• 클래스를 유일하게 만들어주는 식별자
• 전체 클래스 이름 = 상위패키지.하위패키지.클래스
• 클래스명이 같아도 패키지명이 다르면 다른 클래스로 취급
6.12.1 패키지 선언
패키지는 클래스를 컴 파일 하는 과정에서 자동적으로 생성되는 폴더이다.
컴파일러는 클래스에 포함되어 있는 패키지 선언을 보고, 파일 시스템의 폴더로 자동 생성시킨다.
package 상위패키지.하위패키지;
public class ClassName{.....}
패키지 명명 규칙
- 숫자로 시작해서는 안되고, _,$를 제외한 특수문자를 사용해서는 안된다.
- java로 시작하는 패키지는 자바 표준 API에서만 사용하므로 사용해서는 안된다.
- 모두 소문자로 작성하는것이 관례이다.
6.12.4 import문
같은 패키지에 속하는 클래스들은 아무런 조건 없이 다른 클래스를 사용할 수 있다.
하짐나 다른 패키지에 속한 클래스를 사용하기 위해서는 두가지 방법 중 하나를 선택해야 한다.
1) 패키지와 클래스를 모두 기술한다.
2) 사용하고자 하는 package를 import문으로 선언하고 클래스를 사용할 때는 패키지를 생략한다.
//1번방법
package com.mycompany;
public class Car{
com.hankook.Tire tire = new com.hankook.Tire();
}
//2번방법
package com.mycompany;
import com.hankook.Tire;
public class Car{
Tire tire = new Tire();
}
6.13 접근 제한자
- 클래스 및 클래스의 구성 멤버에 대한 접근을 제한하는 역할
• 다른 패키지에서 클래스를 사용하지 못하도록 (클래스 제한)
• 클래스로부터 객체를 생성하지 못하도록 (생성자 제한)
• 특정 필드와 메소드를 숨김 처리 (필드와 메소드 제한)
main() 메소드를 가지지 않는 대부분의 클래스는 외부 클래스에서 사용할 목적으로 설계된 라이브러리 클래스이다.
라이브러리 클래스를 설계할때에는 외부 클래스에서 접근할 수 있는 멤버와 접근 할 수 없는 멤버로 구분해서 필드, 생성자, 메소드를 설계하는 것이 바람직하다.
접근제한자 종류
6.14 Getter와 Setter 메소드
클래스 선언할 때 필드는 일반적으로 private 접근 제한
- 읽기 전용 필드가 있을 수 있음 (Getter의 필요성)
- 외부에서 엉뚱한 값으로 변경할 수 없도록 (Setter의 필요성)
예를들어 자동차의 속도는 -가 될 수 없는데 -로 변경하려고 한다면 무결성이 깨지게 된다.
setSpeed() 메소드로 변경할 경우 다음과 같이 검증 코드를 작성할 수 있다.
void setSpeed(double speed){
if(speed <0){
this.speed = 0;
return;
}else{
this.speed= speed;
}
}
메소드로 필드 값을 가공한 후 외부로 전달하기 위해 getter를 사용한다.
double getSpeed(){
double km = speed*1.6; // 필드 값인 mile을 km단위로 환산 후 리턴
return km;
}
6.15 어노테이션 (Annotation)
- 프로그램에게 추가적인 정보를 제공해주는 메타데이터(metadata)
- 어노테이션 용도
• 컴파일러에게 코드 작성 문법 에러 체크하도록 정보 제공
• 소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동 생성하게 정보 제공
• 실행 시(런타임시) 특정 기능 실행하도록 정보 제공
어노테이션은 메타데이터라고 볼 수 있다.
메타데이터란 애플리케이션이 처리할 데이터가 아니라, 컴파일 과정과 실행 과정에서 코들르 어떻게 컴파일 하고 처리할 것인지를 알려주는 정보이다.
@AnnotationName
6.15.1 어노테이션 타입 정의와 적용
어노테이션 타입을 정의하는 방법은 인터페이스를 정의하는 것과 유사하다.
다음과 같이 @interface를 사용해서 어노테이션을 정의하며, 그 뒤에 사용할 어노테이션 이름이 온다.
public @interface AnnotationName{
}
이렇게 정의한 어노테이션은 코드에서 다음과 같이 사용된다.
@AnnotationName
어노테이션은 엘리먼트(element)를 멤버로 가질 수 있다.
public @interface AnnotationName{
타입 elementName() [default값];
}
public @interface AnnotationName{
String elementName1();
int elemnetName2() default 5;
}
6.15.2 어노테이션 적용 대상
어노테이션을 적용할 수 있는 대상은 java.lang.annotation.ElementType 열거 상수로 다음과 같이 정의되어 있다.
6.15.3 어노테이션 유지 정책
- 어노테이션 적용 코드가 유지되는 시점을 지정하는 것
- java.lang.annotation.RetentionPolicy 열거 상수로 정의
'JAVA > 이것이 자바다' 카테고리의 다른 글
Chapter .08 인터페이스 (0) | 2021.07.19 |
---|---|
Chapter .07 상속 (0) | 2021.07.17 |
Chapter .06-1 클래스 (0) | 2021.07.14 |
Chapter .05 참조 타입 (0) | 2021.07.06 |
Chapter .04 조건문과 반복문 (0) | 2021.07.05 |