반응형
- 정적(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 필드:
- – 객체마다 여러가지 값으로 초기화 될 수 있다.
- – 상수라 할 수 없고 인스턴스 멤버이다.
- • 상수(static final):
- – 객체마다 따로 관리할 필요 없는 공용 데이터
- – 상수이며 정적 멤버이다.
- • final 필드:
- 상수 이름은 전부 대문자로 작성
- 다른 단어가 결합되면 _ 로 연결
- 패키지(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
- 동일 패키지와 해당클래스를 상속한 클래스에서 접근가능하다.
- 상속에서 알아보고 지금은 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 버튼 클릭
반응형
'학습 > JAVA' 카테고리의 다른 글
7. 상속(Inheritance) (Override, Annotation, toString()) (1) | 2022.10.11 |
---|---|
7. 상속(Inheritance) (상속, 부모 생성자 호출 super()) (0) | 2022.10.11 |
6. 클래스(메소드, 인스턴스 멤버와 this) (0) | 2022.10.06 |
6. 클래스(생성자) (0) | 2022.10.05 |
5. 열거 타입 (0) | 2022.10.05 |
댓글