인스턴스 멤버
- 객체들 마다 다른 값을 가질 수 있는 객체들 소유의 구성요소
정적 멤버
- 해당 타입(클래스)가 고유하게 가지며 모든 객체들이 동일하게 가져야하는 값들을 정의할 때 사용하는 구성요소(클래스 소유 구성요소)
- 객체를 생성하지 않고 클래스를 통해 사용
- 접근할 때 클래스 소속의 구성요소이기 때문에 클래스를 통하여 접근할 수 있다.
정적 필드
- 모든 객체가 해당 타입에서 고유한 값을 갖는 필드의 경우 정적필드로 선언
- 생성자에서 초기화를 하지 않는다 (정적 필드는 객체 생성 없이 사용할 수 있기 때문에 생성자에서
초기화 작업을 하지 않는다. 생성자는 객체 생성 후 실행되기 때문이다.) - 필드 선언과 동시에 초기값을 주는게 일반적
정적 메소드
- 메소드 내부에서 인스턴스 멤버를 사용하지 않는 경우 정적 메소드로 선언 (경우에 따라서)
- static메소드는 클래스의 구성요소이기 때문에 객체보다 먼저 로드된다.
그래서 정적 메소드 내부에서는 인스턴스 구성요소를 그냥 접근할 수 없다. - 정적 멤버에서 인스턴스 멤버가 반드시 필요한 경우 강제로 객체를 생성하여 접근할 수 있다.
public class CalculatorStatic {
static int plus(int num1,int num2) {
int sum = num1 + num2;
return sum;
}
static int minus(int num1,int num2) {
int result = num1 - num2;
return result;
}
static int multi(int num1,int num2) {
return num1 * num2;
}
static double devide(int num1,int num2) {
return (double)num1 / num2;
}
public static void main(String[] args) {
int result = CalculatorStatic.plus(10, 20);
System.out.println(result);
result = CalculatorStatic.minus(20,10);
System.out.println(result);
}
}
정적 초기화 블럭
- 연산을 통해 정적필드를 초기화 해야하는 경우 사용
- 최초 클래스 메소드 영역에 로드되는 시점에 단 한번만 실행
- 정적 필드는 클래스의 생성자를 통해 값을 초기화 할 수 없기 때문에 정적 초기화 블럭을 사용하여 필드를 초기화 할 수 있다.
- 객체가 생성되는 시점보다 먼저 정적필드가 초기화되기 때문에 static 블럭에서는 인스턴스 멤버를 사용할 수 없다.
- 굳이 써야한다면 객체를 생성하고 사용하면 된다.
static {
}
final 키워드를 가지는 필드는 초기값을 반드시 부여해야한다. 부여된 초기값을 절대 변경할 수 없다.(최종의 값)
final 필드를 초기화하는 방법
1)필드에 직접 초기값을 대입하는 방법
:만들어지는 모든 객체들이 같은 값을 고유하게 갖는다.
2)생성자를 통하여 필드를 초기화하는 방법
:만들어지는 모든 객체들이 각각 다른 값을 고유하게 갖는다.
상수
- 변하지 않는 절대적인 값
- 정적 필드이며 초기값을 변경할 수 없는 단하나만 존재하는 절대적인 값을 의미
- final과 static 키워드를 조합하여 선언한다.
- 상수명은 관례적으로 대문자를 사용하여 선언한다.
public class FinalExClass {
final String field01 = "finaldata";
String field02;
final String field03;
FinalExClass(String field03){
this.field03 = field03;
}
public static void main(String[] args) {
FinalExClass fc = new FinalExClass("field03Data01");
//fc.field01 = "data01";
fc.field02 = "data02";
//fc.field01 = "data03";
//fc.field03 = "수정"; final필드는 초기값을 수정할 수 없다.
FinalExClass fc2 = new FinalExClass("다른 데이터 가짐");
System.out.println(fc.field03);
System.out.println(fc2.field03);
}
}
public class Earth {
//상수 선언 및 초기화
static final double EARTH_RADIUS = 6400;
//상수 선언
static final double EARTH_SURFACE_AREA;
//정적 블록에서 상수 초기화
static {
//상수 초기화 가능
EARTH_SURFACE_AREA = 4 * Math.PI * EARTH_RADIUS * EARTH_RADIUS;
}
public static void main(String[] args) {
System.out.println("지구의 반지름: " + Earth.EARTH_RADIUS + "km");
System.out.println("지구의 표면적: " + Earth.EARTH_SURFACE_AREA + "km^2");
}
}
패키지
- 폴더 역할
- 같은 패키지 내에서는 클래스를 사용할 때 클래스의 패키지를 생략할 수 있다.
- 다른 패키지의 클래스를 사용할 때는 반드시 패키지명까지 전부 작성하여 클래스를 사용한다.
import
- 다른 패키지에 있는 클래스를 사용하기 위해 사용
- 하위 패키지를 포함하지 않음
com.hankook 패키지에 있는 클래스도 사용해야하고, com.hankook.project 패키지도 사용해야 한다면
com.hankook.*;
com.hankook.project.*;
2개의 import문을 선언해줘야한다.
서로 다른 패키지에 동일한 클래스 이름이 존재하고 이 클래스들을 사용하려고 할 경우 이름이 같기 때문에 오류가 발생.
이 경우 클래스 전체의 이름을 사용해서 정확히 어떤 패키지의 클래스를 사용하는지 알리면 된다. 이 경우 import문은 필요 없다.
import javastudy.ch03.Ex02_Prefix_Increment_Decrement;
public class Earth {
public static void main(String[] args) {
javastudy.ch02.Ex01 ex01 = new javastudy.ch02.Ex01();
//javastudy.ch03 패키지 안에 있는 Ex02 클래스를 사용하여 객체를 생성
//이때 ex02 변수에 생성된 객체에 참조
Ex02_Prefix_Increment_Decrement ex02 = new Ex02_Prefix_Increment_Decrement();
}
}
이클립스에서 import문을 자동으로 추가하는 단축키
ctrl + shift + o(알파벳 o)
접근제한자
- 자바에서 캡슐화를 진행할 수 있는 구성요소이다
- 접근제한자를 사용할 수 있는 위치 : 클래스, 생성자, 메소드, 필드
- 접근제한자의 종류에 따라 접근 범위가 달라진다.
접근제한자의 종류
1)public : 전체공개(패키지를 벗어나도 접근 가능) / 클래스, 생성자, 메소드, 필드
2)protected : 같은 패키지와 상속된 자식 클래스에서만 접근 가능 / 생성자, 메소드, 필드
3)default : 같은 패키지 내에서만 접근 가능 / 클래스, 생성자, 메소드, 필드
4)private : 해당 클래스 내에서만 접근 가능 / 생성자, 메소드, 필드
setter와 getter
- private 접근제한을 갖는 필드들에 데이터를 채우거나 얻을 때 사용하는 메소드
- 주로 필드들은 private 접근 제한을 갖는 경우가 많다.
이유는 외부에서 논리적으로 맞지 않는 데이터를 대입해 객체가 손상될 수 있기 때문이다.
1)setter
-private 필드들에게 데이터를 채우는 용도의 메소드들을 일컷는다.
문법)
public void set필드명(매개변수) {
this.필드명 = 매개변수;
}
필드명은 카멜기법 사용/매개변수 타입은 setting하고자하는 필드의 데이터타입
2)getter
-private 필드들의 데이터를 읽는 용도의 메소드들을 일컷는다.
문법)
public 리턴타입 get필드명() {
return 필드명;
}
리턴타입은 반환하고자 하는 필드의 데이터타입과 동일
필드명(메소드명)은 카멜기법 사용
엔티티 클래스
-생성되는 객체들이 속성값을 가지고 있을 목적의 클래스를 의미한다.
-필드들은 private 접근제한을 가지며 setter와 getter를 통하여
데이터를 대입 또는 읽게 끔 한다.
public class Account {
private String bankName; //은행명
private String name; //계좌주
private String accountNo; //계좌번호
private int balance; //잔고
final static private int MIN_BALANCE = 0;
final static private int MAX_BALANCE = 1000000;
/*
1)accountNo는 6자리일때만 대입가능
2)balance는 음수 대입 불가능
*/
public String getBankName() { return bankName; }
public String getName() { return name; }
public String getAccountNo() { return accountNo; }
public int getBalance() { return balance; }
public void setBankName(String bankName) { this.bankName = bankName; }
public void setName(String name) { this.name = name; }
public void setAccountNo(String accountNo) {
if(accountNo.length() == 6) {
this.accountNo = accountNo;
}else {
System.out.println("계좌번호를 잘못 입력하셨습니다.");
}
}
public void setBalance(int balance) {
if(balance < MIN_BALANCE || balance > MAX_BALANCE) {
System.out.println("알맞지 않은 값입니다. 잔고는 1,000,000원까지만 저장할 수 있습니다.");
}else {
this.balance = balance;
}
}
public static void main(String[] args) {
Account account = new Account();
account.setBalance(10000);
System.out.println("현재잔고 : " + account.getBalance());
System.out.println();
account.setBalance(-100);
System.out.println("현재잔고 : " + account.getBalance());
System.out.println();
account.setBalance(2000000);
System.out.println("현재잔고 : " + account.getBalance());
System.out.println();
account.setBalance(300000);
System.out.println("현재잔고 : " + account.getBalance());
}
}
싱글톤
- 시스템에서 단 하나만 존재하는 객체이며 모든 곳에서 공유하여 사용할 수 있다.
- 생성자를 외부에서 접근하지 못하게 만들어야함 private 생성자() {}
싱글톤 만들기
1)생성자를 private 접근제한자로 외부에서 객체를 무분별하게 생성하는 것을 방지
2)싱글톤 클래스 타입의 정적 필드를 선언 후 생성자를 통해 단하나의 객체를 생성하여 대입
3)해당 정적 필드를 접근제한을 private로 선언하여 외부에서 데이터 변경 안되도록 하기
4)싱글톤 객체를 반환할 수 있는 getInstance 메소드를 정의한다.
static도 선언해줘야 함. private여서 객체를 만들수없기 때문에
public class SingletonClass {
private SingletonClass(){}
private static SingletonClass singletonClass = new SingletonClass();
public static SingletonClass getInstance() {
return singletonClass;
}
}
SingletonClass sc1 = SingletonClass.getInstance();
SingletonClass sc2 = SingletonClass.getInstance();
System.out.println(sc1 == sc2);
public class ShopService {
private ShopService() {};
private static ShopService shopService = new ShopService();
public static ShopService getInstance() {
return shopService;
}
public static void main(String[] args) {
ShopService obj1 = ShopService.getInstance();
ShopService obj2 = ShopService.getInstance();
if(obj1 == obj2) {
System.out.println("같은 ShopService 객체입니다.");
}else {
System.out.println("다른 ShopService 객체입니다.");
}
}
}
'Java' 카테고리의 다른 글
[Java] 인터페이스 (0) | 2024.08.06 |
---|---|
[Java] 상속, 메소드 오버라이딩, 추상클래스 (0) | 2024.08.03 |
[Java] class, 필드, 생성자, 메소드, 오버로딩 (0) | 2024.07.31 |
[Java] 배열, 향상된 for문, 열거 (0) | 2024.07.29 |
[Java] String, String이 제공하는 기능들 (0) | 2024.07.28 |