본문 바로가기
학습/JAVA

6. 클래스(정적(static), 인스턴스, 싱글톤(singleton), 상수, 접근 제한자, Getter & Setter

by Elfen Lied 2022. 10. 7.
반응형

- 정적(static) 멤버

  • 클래스에 고정된 필드와 메소드 - 정적 필드, 정적 메소드
  • 정적 멤버는 클래스에 소속된 멤버
    • 객체 내부에 존재하지 않고, 메소드(스태틱) 영역에 존재
    • 정적 멤버는 객체를 생성하지 않고 클래스로 바로 접근해 사용
  • 원칙적으로 정적 메소드를 호출할 때는 클래스명.메소드명()으로 호출한다.
  • 동일 클래스내에서는 위 예제처럼 클래스명을 생략하고 호출할 수 있다.
  • 외부에서 접근할 때는 반드시 클래스명을 명시해야한다.
public class Calculator {

	static double pi = 3.14;
	
	static int add(int x, int y) {
		return x + y;
		
	}
	
	int plus(int x, int y) {
		return x + y;
	}
	
	public static void main(String[] args) {
		// 클래스 내부에 스테틱 메소드 호출
		int result = Calculator.add(5, 7);
		int result2 = add(5, 7);
		System.out.println(result);
		System.out.println(result2);

		// 클래스 내부에서 인스턴스 메소드 호출
		// 객체생성 해야한다.
		// 인스턴스 메소드는 내부든 외부든 객체 생성해야함
		Calculator calculator = new Calculator();
		int result3 = calculator.plus(10, 2);
		System.out.println(result3);
		
	}
}

 

 

 

- 인스턴스 멤버 선언 vs 정적 멤버 선언의 기준

- 필드

  • 객체 마다 가지고 있어야 할 데이터 ➔ 인스턴스 필드
  • 공용적인 데이터 ➔ 정적 필드

- 메소드

  • 인스턴스 필드로 작업해야 할 메소드 ➔ 인스턴스 메소드
  • 인스턴스 필드로 작업하지 않는 메소드 ➔ 정적 메소드

 

- static 초기화

public class Card {

	int cardNumber; // 카드 숫자(인스턴스)
	static int cardWidth; // 가로 길이(정적)
	static int cardHeight; // 세로 길이(정적)
	
	public Card() {
		// 정적멤버, 비정적 멤버 모두 사용가능
		System.out.println(cardWidth); // 정적멤버
		this.cardNumber = 8; // 비정적멤버
	}
	
	static {
		// 정적멤버 사용가능
		cardWidth = 90;
		cardHeight= 55;
		
		// 비정적멤버를 사용할 수 없다.
//		cardNumber = 10;
//		getCardNumber();
	}
	
	
	// 스테텍 메소드
	static void infoCardSize() {
		// 정적 멤버 사용 가능
		System.out.println(cardWidth);
		System.out.println(cardHeight);
		getMessage();
		
		// 비정적멤버를 사용할 수 없다.
//		cardNumber = 10;
//		getCardNumber();
	}
	
	static void getMessage() {
		System.out.println("Hello");
	}
	

	// 인스턴스 메소드
	int getCardNumber() {
		// 정적멤버, 비정적 멤버 모두 사용가능
		getMessage();
		cardNumber = 100;
		cardWidth = 80;
		cardHeight = 40;
		return this.cardNumber;
	}
	
	public static void main(String[] args) {
		infoCardSize();
//		Card card = new Card();
//		int result =  card.getCardNumber();
//		System.out.println(result);
	
	}
}

정적 멤버와 인스턴스 멤버를 게임으로 설명해보면

정적(static)은 월드맵처럼 로딩없이 언제나 준비중

인스턴스 멤버는 인스턴스 던전처럼 던전에 입장을 해야 생성이 된다. 


 

- 싱글톤(Singleton)

  • 하나의 애플리케이션 내에서 단 하나만 생성되는 객체

 

- 싱글톤을 만드는 방법

  • 외부에서 new 연산자로 생성자를 호출할 수 없도록 막기
    • private 접근 제한자를 생성자 앞에 붙임
  • 클래스 자신의 타입으로 정적 필드 선언
    • 자신의 객체를 생성해 초기화
    • private 접근 제한자 붙여 외부에서 필드 값 변경 불가하도록
  • 외부에서 호출할 수 있는 정적 메소드인 getInstance() 선언
    • 정적 필드에서 참조하고 있는 자신의 객체 리턴
public class SingleTon {
	
	private static SingleTon singleTon = new SingleTon();
	
	private SingleTon() {
		// 외부에서 객체를 생성하지 못하도록 한다.
	}
	
	// 이 정적 메소드를 통하여 생성된 객체를 얻는다.
	public static SingleTon getInstance() {
		return singleTon;
	}
}

==============================================================

public class SingleTonExam {
	public static void main(String[] args) {
//		SingleTon obj1 = new SingleTon(); // 컴파일 에러
//		SingleTon obj2 = new SingleTon(); // 컴파일 에러
		
		SingleTon obj1 = SingleTon.getInstance();
		SingleTon obj2 = SingleTon.getInstance();
		System.out.println(obj1);
		System.out.println(obj2);
		System.out.println(obj1 == obj2); // false
	}
}

 

 

 

- final 필드

  • final 필드는 한 번 초기화 되면 값을 변경할 수 없다.
  • final 필드는 다음의 둘 중에 반드시 초기화 되어야 한다.
    • 필드 선언 시
    • 생성자
    • Final 필드가 초기화 되지 않으면 컴파일 에러가 발생한다.
public class Person {
	final String nation;
	final String ssn;
	String name;
	
	public Person() {
		nation = "대한민국";
		ssn = "777777777";
	}
	
	// final 필드 : 생성자의 매개값으로 초기화 가능
	public Person(String nation, String ssn) {
		this.nation = nation;
		this.ssn = ssn;
	}
}

======================================================

public final class PersonExam {
	public static void main(String[] args) {
		// final이 가능한 곳 : 필드(재할당 불가), 클래스(상속 불가)
		
		Person person = new Person();
		person.name = "고길동";
		
		// final 필드 재할당 불가능
//		person.nation = "미국";
//		person.ssn = "러시아";
		
		Person person2 = new Person("프랑스", "000");
		person2.name = "마크롱";
//		person2.nation = "영국";
//		person2.ssn = "222222";
		
	}
}

 

 

 

- 상수(static final)

  • 상수 : 정적 final 필드
  • final필드와 static final필드는 초기화 된 값을 변경할 수 없다.
    • • final 필드:
      1. – 객체마다 여러가지 값으로 초기화 될 수 있다.
      2. – 상수라 할 수 없고 인스턴스 멤버이다.
    • • 상수(static final):
      1. – 객체마다 따로 관리할 필요 없는 공용 데이터
      2. – 상수이며 정적 멤버이다.
  • 상수 이름은 전부 대문자로 작성
  • 다른 단어가 결합되면 _ 로 연결

 

 

 

- 패키지(package)

  • 클래스를 기능별로 묶어서 그룹 이름을 붙여 놓은 것
    • 파일들을 관리하기 위해 사용하는 폴더(디렉토리)와 비슷한 개념
    • 패키지의 물리적인 형태는 파일 시스템의 폴더
  • 클래스 이름의 일부
    • 클래스를 유일하게 만들어주는 식별자
    • 전체 클래스 이름 = 상위패키지.하위패키지.클래스
    • 클래스명이 같아도 패키지명이 다르면 다른 클래스로 취급
  • ▪ 클래스 선언할 때 패키지 결정
    • • 클래스 선언할 때 포함될 패키지 선언
    • • 클래스 파일은(~.class) 선언된 패키지와 동일한 폴더 안에서만 동작
    • • 클래스 파일은(~.class) 다른 폴더 안에 넣으면 동작하지 않음

 

 

- import 문

  • 패키지 내에 같이 포함된 클래스간 클래스 이름으로 사용 가능
  • 패키지가 다른 클래스를 사용해야 할 경우

 

 

 

- 접근 제한자(Access Modifier)

  • 클래스 및 클래스의 구성 멤버에 대한 접근을 제한하는 역할
    • 다른 패키지에서 클래스를 사용하지 못하도록 (클래스 제한)
    • 클래스로부터 객체를 생성하지 못하도록 (생성자 제한)
    • 특정 필드와 메소드를 숨김 처리 (필드와 메소드 제한)
  • 클래스 접근제한자: public, default
    • 즉 클래스에서 사용할 수 있는 접근제한자는 public 뿐이다.
  • 필드, 메소드 접근제한자 : public, protected, default, private
    • default 예약어는 따로 존재하지 않는다. 접근제한자를 생략하면
    • default 접근 제한이 설정된다

-  접근 제한자의 종류

// 접근 제한자 default

package sec.modifier;

class AAA {
	
}

package sec.modifier;

public class BB {

}

====================================

package sec.modifier;

public class AAADemo {
	public static void main(String[] args) {
		// AAADemo클래스와 AAA, BB클래스는 동일한 패키지 내에 존제
		// 디폴트 접근제한자를 가지는 AAA클래스의 인스턴스를 생성할 수 있음
        // BB 동일 클래스 내에 존재하므로 생성 가능
		AAA aaa = new AAA();
        
        BB bb = new BB();
	}
}

====================================

package sec.default_test;

import sec.modifier.BB;

public class AADemo {
	public static void main(String[] args) {
		// AADemo클래스와 AAA클래스는 서로 다른 패키지 내에 존재
		// AAA클래스가 디폴트 접근제한자를 가지므로
		// AAADemo클래스 내에서 AAA객체를 생성할 수 없음
        // BB클래스는 public 접근제한자이므로 import해서 생성 가능
//		AAA aaa = new AAA();
		
		// public 접근자의 BB클래스
		BB bb = new BB();
	}
}

 

 

- 생성자 접근 제한

  • 생성자 접근 제한
    • 생성자가 가지는 접근 제한에 따라 호출 여부 결정
  • 필드와 메소드의 접근 제한 (p.262~264)
    • 클래스 내부, 패키지 내, 패키지 상호간에 사용할 지 고려해 선언
  • 필드, 생성자, 메소드 접근제한자 규칙
    • public : 모든 패키지에서 접근 가능하다.
    • default : 동일 패키지내에서 접근 가능하다.
    • private : 해당 클래스 내부에서만 사용할 수 있다.
    • protected
      1. 동일 패키지와 해당클래스를 상속한 클래스에서 접근가능하다.
      2. 상속에서 알아보고 지금은 default 처럼 생각한다.

 

 

 

- Getter와 Setter

  • 클래스 선언할 때 필드는 일반적으로 private 접근 제한
    • 읽기 전용 필드가 있을 수 있음 (Getter의 필요성)
    • 외부에서 엉뚱한 값으로 변경할 수 없도록 (Setter의 필요성)

 

- Getter

  • private 필드의 값을 리턴 하는 역할 - 필요할 경우 필드 값 가공
  • getFieldName() 또는 isFieldName() 메소드
    • 필드 타입이 boolean 일 경우 isFieldName()

 

 

- Setter

  • 외부에서 주어진 값을 필드 값으로 수정
    • 필요할 경우 외부의 값을 유효성 검사
  • setFieldName(타입 변수) 메소드
    • 매개 변수 타입은 필드의 타입과 동일
public class Car {
	private int speed;
	private boolean stop;
	
	public Car(int speed, boolean stop) {
		this.speed = speed;
		this.stop = stop;
	}
	
	void run() {
		System.out.println("~~~~~~~~~~~run~~~~~~~~~~~");
	}
	
	// getter 메소드
	// 이름 필드의 첫글자 대문자로 변경
	// 접두사로 get을 붙임 getSpeed()
	// 접근제한자 : public
	
	public int getSpeed() {
		return speed;
	}
	
	public boolean getStop() {
		return stop;
	}
	
	// setter 메소드
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	
	public void setStop(boolean stop) {
		this.stop = stop;
	}
}


==================================================

public class CarDemo {
	public static void main(String[] args) {
		Car car = new Car(100, false);
		car.run();
		
		car.setSpeed(200);
		car.setStop(true);
		
		System.out.println(car.getSpeed());
		System.out.println(car.getStop());
	}
}

값
~~~~~~~~~~~run~~~~~~~~~~~
200
true

getter, setter 단축키 

shift + alt + s 누르고

Generate Getters and Setters 선택

원하는 get, set 선택후 아래쪽 Generate 버튼 클릭

 

반응형

댓글