2025.03.04 ~ 03.05
서로 다른 타입의 데이터와 메소드를 정의하여 사용자 정의의 타입을 만든 것.
-> 사용자 정의의 자료형
접근제어자 class 클래스명{
자료형 변수; // 이 부분은 필드라고 함 ( 필드 변수 )
자료형 변수;
}
public class Member{
자료형 변수;
}
Member member = new Member(); // member 는 레퍼런스변수명
필드에 접근하기 위해서는 레퍼런스변수명.필드명 으로 접근
클래스에 간접적으로 접근하여 사용할 수 있도록 클래스를 작성하는 기법

this는 인스턴스(객체)가 생성되었을 때 자신의 주소를 저장하는 레퍼런스 변수
-> 지역변수와 전역변수의 이름이 동일한 경우 지역변수를 우선적으로 접근하기 때문에 전역변수에 접근하기 위해서 this.을 명시해야 한다.
위의 네 가지 접근제한자는 클래스의 멤버(필드, 메소드)에 모두 사용 가능하다.
단, 클래스 선언 시 사용하는 접근제한자는 public과 default만 사용 가능하다.
유연성을 확보하기 위해 공통적인 것을 추출하고 공통적이지 않은 것을 제거하는 것
객체와 객체는 메세지(메소드 호출)을 통해 서로 상호작용을 한다.
-> 그 메세지에 해당하는 내용을 처리하는 방법을 스스로 결정한다.
메소드(method) : 스스로 결정한 방식대로 명령어를 순차적으로 기술한 것
-> 필드보다 메소드를 중점적으로 추상화 기법을 적용하여 객체를 설계하는 것이 중요
행위 위주가 아닌 데이터를 하나로 뭉치기 위한 객체
필드값을 변경할 목적의 매개변수를 변경하려는 필드와 같은 자료형으로 선언하고 호출 당시 전달되는 매개변수의 값을 이용하여 필드의 값을 변경한다.
public void set필드명(매개변수) {
필드 = 매개변수;
}
public void setName(String name) {
this.name = name;
}
각 접근자는 하나의 필드에만 접근하도록 한다.
필드에 접근해서 기록된 값을 return을 이용하여 반환하며, 이 때 반환타입은 반환하려는 값의 자료형과 일치시킨다.
public 반환형 get필드명() {
return 반환값;
}
public void getName() {
return this.name;
}
public boolean isActivated() {
return isActivated;
}
boolean의 접근자는 get으로 시작하지 않고 is로 시작하는 것이 일반적인 관례이다.
인스턴스를 생성할 때 초기 수행할 명령이 있는 경우 미리 작성해두고, 인스턴스를 생성할 때 단 한 번 호출되는 함수
접근제한자 클래스명(매개변수) {
인스턴스 생성 시점에 수행할 명령 기술 (주로 필드를 초기화)
this.필드명 = 매개변수; //설정자(setter) 여러 개의 기능을 한 번의 호출로 수행할 수 있다.
}
동일 클래스 내에 작성한 다른 생성자 메소드를 호출하는 구문
장점
단점
장점
단점
동일한 클래스 내에는 동일한 이름의 생성자 / 메소드를 작성하지 못한다.
하지만 매개변수의 타입, 갯수, 순서를 다르게 작성하면 서로 다른 생성자 / 메소드로 인식하기 때문에 동일한 이름의 생성자 / 메소드를 여러개 작성할 수 있게 해줌.
public void method(int num) {} 이라는 메소드의 메소드명과 파라미터 선언부 부분을 시그니쳐라고 부른다.
method(int num) 이 부분이 시그니처
-> 메소드명은 동일 해야 하고 매개변수 부분이 다르게 설정하면 오버로딩된다.
정적 메모리 영역에 프로그램이 start될 시 할당 하고자 할 때 사용하는 키워드
애플리케이션이 시작될 때 어떤 클래스가 최초 한 번만 메모리를 할당하고 그 메모리에 인스턴스를 만들어서 하나의 인스턴스를 공유해서 사용하며 메모리 낭비를 방지할 수 있게 함 (매번 인스턴스 생성 하지 않음)
생성자를 이용하여 직접 인스턴스 생성을 하지 못하고 getInstance() 메소드를 호출해야만 인스턴스를 생성할 수 있다. *
장점
단점
클래스가 초기화 되는 시점에서 인스턴스를 생성한다.
첫 번째 getInstance() 호출 시 딜레이 없음.
static 필드로 미리 인스턴스를 생성해 둔다. -> 인스턴스를 사용하지 않아도 메모리 차지
클래스를 로드하는 속도가 느려지지만 처음 인스턴스 반환 요청에서 속도가 빠르다는 장점을 가진다.

인스턴스를 필요할 때 생성하는 방식 (처음 getInstance() 호출 시 생성).
-> 클래스가 초기화 되는 시점에서는 정적 필드를 선언해두고 null로 초기화된다.
클래스를 로드하는 속도는 빠르지만 첫 번째 요청에 대한 속도가 두 번째 요청에 대한 속도보다 느리다는 특징을 가진다. 
변경 불가의 의미를 담고 있는 키워드
상속과 관련하여 클래스나 메소드의 예약어 자리에 쓰이면 더 이상 하위 클래스에서 가지지 못하는 마지막 클래스나 메소드를 의미하게 된다.
클래스 필드의 final 변수는 선언과 동시에 초기화 하거나 생성자를 초기화를 해야한다.
지역변수 : 초기화 이후 값 변경 불가
매개변수 : 호출시 전달한 인자 변경 불가
전역변수 : 인스턴스 생성 후 초기화 이후에 값 변경 불가
클래스(static) 변수 : 프로그램 start 이후 값 변경 불가
non-static 메소드 : 메소드 재작성(overriding) 불가
static 메소드 : 메소드 재작성(overriding) 불가
클래스 : 상속 불가

레퍼런스변수에 대한 배열
클래스명(사용자 지정 참조 자료형)[] 참조변수명 = new 클래스명[배열 크기]; //먼저 배열할당
참조변수명[인덱스] = new 클래스명(매개변수);
참조변수명[인덱스] = new 클래스명(매개변수);
해당 클래스의 인스턴스 생성 시 어떤 생성자를 활용해서 인스턴스를 생성하더라도 공통적으로 실행 될 코드를 작성할 수 있는 블럭
-> 복잡한 초기화를 수행할 수 있는 블럭
인스턴스가 생성되는 시점에 생성자 호출 이전에 먼저 실행이 된다.
인스턴스를 호출하는 시점마다 호출이 된다.
인스턴스변수를 초기화하며 정적필드에는 실행시점마다 값을 덮어쓴다.
{
초기화 내용 작성
}
클래스가 로드될 때 한 번 동작한다.
정적 필드를 초기화하며, 인스턴스변수는 초기화하지 못한다.
static {
초기화 내용 작성
}

초기화 순서
인스턴스변수 : 기본값 -> 명시적초기값 -> 인스턴스초기화블럭 -> 생성자
클래스변수 : 기본값 -> 명시적초기값 -> 정적초기화블럭 -> 인스턴스초기화블럭 -> 생성자
오른쪽으로 갈 수록 더 강한 힘을 가져서 덮어쓴다.
객체는 개념!, 인스턴스는 구체적인 예시!
<!-- 생성자 안 만든 경우 -->
class Person {
String name;
}
Person p = new Person(); // 가능
p.name = "홍길동"; // 가능
<!-- 생성자 만든 경우 -->
class Person {
String name;
Person(String name) {
this.name = name;
}
}
Person p = new Person(); // 불가능
Person p = new Person("홍길동") // 가능
<!-- 기본 생성자를 직접 추가 -->
class Person {
String name;
Person() {} // 기본 생성자 직접 추가
Person(String name) {
this.name = name;
}
}
Person p1 = new Person(); // 가능
Person p2 = new Person("홍길동"); // 가능
<!-- setter 없이 public 변수 -->
class Person {
String name;
}
Person p = new Person();
p.name = "홍길동"; // 가능
p.name = "김철수"; // 가능 (언제든 변경됨)
<!-- private + setter -->
class Person {
private String name;
void setName(String name) {
this.name = name;
}
}
Person p = new Person();
p.name = "홍길동"; // 불가능
p.setName("홍길동"); // 가능
p.setName("김철수"); // 가능 (값 계속 변경됨)
<!-- private만 사용 -->
class Person {
private String name;
}
Person p = new Person();
p.name = "홍길동"; // 불가능
<!-- private + final + 생성자 -->
class Person {
private final String name;
Person(String name) {
this.name = name;
}
}
Person p = new Person("홍길동");
p.name = "김철수"; //불가능
// setter도 만들 수 없음 (final이라 에러)
<!-- 요즘 가장 많이 쓰는 방식 -->
class User {
private final String name;
private final int age;
private String password;
User(String name, int age) {
this.name = name;
this.age = age;
}
void changePassword(String newPassword) {
// 검증 조건 추가
this.password = newPassword;
}
public String getName() {
return name;
}
}