자바 클래스 2

Dear·2025년 5월 16일

TIL

목록 보기
23/74

💙 다형성

하나의 클래스나 함수가 다양한 방식으로 동작 가능한 것.

오버로딩과 오버라이딩을 통해서 다형성 구현이 가능하다.

💙 메소드 오버로딩

같은 메소드를 타입이나, 매개변수 갯수, 매개변수 타입을 다르게 해서 사용

int divide(int x, int y){ ... }
double divide(int boonja,  int boonmo) { ... } 

💙 생성자 오버로딩

public class Car {
	Car() { ... }
	Car(String model) { ... }
	Car(String model, String color) { ... }
	Car(String model, String color, int maxSpeed) { ... }
}

💙 초기화(Initialization)

변수나 객체를 사용하기 전에 값을 할당하거나 초기 상태로 설정하는 과정을 말한다.
초기화는 안정적인 실행을 보장하는데 중요한 역할을 한다.

초기화 시점

클래스 변수 : 클래스가 처음 로딩될때 단 한번 초기화 된다.
인스턴스 변수 : 인스턴스가 생성될 때마다 각 인스턴스 별로 초기화가 이루어진다.

💙 클래스 멤버 변수 초기화 순서

  1. static 변수 선언
    클래스가 로드 될때 (메소드 영역) 변수가 제일 먼저 초기화된다.
  2. 필드 변수 선언부
    객체 생성 될 때(힙 영역) 생성자 block보다 앞서 초기화된다.
  3. 생성자 block
    객체 생성 될 때(힙 영역) JVM이 내부적으로 locking(thread safe 영역)
    필드 변수 중 final 변수의 가시화는 (다른 스레드에 공개) 생성자 block이 끝난 다음 필드 변수 선언부에서 이미 초기화 되었다면 그 값들은 덮어 씀

클래스 변수
기본값 → 명시적 초기화(초기값 할당 int x = 10; 처럼) → 클래스 초기화 블록
인스턴스 변수
기본값 → 명시적 초기화 → 인스턴스 초기화 블록 → 생성자

💙 정적 멤버(static)

정적(static)은 ‘고정된’이란 뜻으로 정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드. (정적 필드, 정적 메소드)

객체(인스턴스)에 소속된게 아니라 클래스에 소속되어 있다.

클래스 로딩이 끝나면 바로 사용할 수 있다.

객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언하고, 객체마다 가지고 있을 필요성이 없는 공용적인 데이터라면 정적 필드로 선언하는 것이 좋다.

정적 멤버 선언

public class 클래스{
	// 정적 필드
	static 타입 필드 [= 초기값];
	// 정적 메소드
	static 리턴 타입 메소드(매개변수선언, ... ){ ... }
}

public class Calculator {
	static double pi = 3.14159; // 정적 필드 -> 계산기에서 사용하는 파이값은 동일하다.
	String color; // 인스턴스 필드 -> 계산기별로 색깔이 다를 수 있다.

	static int plus(int x, int y) { // 정적 메소드
		return x + y;
	}

	static int minus(int x, int y) { // 정적 메소드
		return x - y;
	}
}

// 객체를 생성하지 않고 바로 클래스(Calculator)로 사용
double result1 = 10 * 10 * Calculator.pi;
int result2 = Calculator.plus(10, 5);
int result3 = Calculator.minus(10, 5);

// 클래스 객체를 만들어서 사용가능하지만 추천 X 
Calculator myCalcu = new Calculator();

double result = 10 * 10 * myCalcu.pi;
int result2 = myCalcu.plus(10, 5);
int result3 = myCalcu.minus(10, 5);
 

정적 초기화가 필요할 경우

public class Television {
	static String company = "Samsung";
	static String model = "LCD";
	static String info;
	
	static {
		info = company + "-" + model;
	}
}
---------------------------------------------------------------------
public class TelevisionExample {
	public static void main(String[] args) {
		System.out.println(Television.info);
	}
}

주의할 점

내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다.

public class MyClass {
    public int instanceField;
    public static int staticField;

    public void instanceMethod() {
        // instanceField에 접근 가능
        // staticField에 접근 가능
    }

    public static void staticMethod() {
        // instanceField에 접근 불가능
        // staticField에 접근 가능
    }
}

객체 자신의 참조인 this 키워드도 사용이 불가능하다.

정적 메소드나 정적 블록에서 인스턴스 멤버를 사용하고 싶다면 객체를 먼저 생성한 후 참조 변수로 접근해야 한다. main() 역시 static 메소드

public class Main{
	public static void main(String args[]){
		// 정적 메소드 호출
		Example.staticMethod();
		
		// 정적 블록에서도 동일한 접근이 가능
		// 예를 들어, 정적 블록에서 인스턴스 멤버 사용 가능
		Example obj = new Example();
		System.out.println(obj.instanceVariable);
		}
}
-------------------------------------------------------------
class Example{
	public int instanceVariable = 10;
	
	public static void staticMethod(){
		// 정적 메소드에서 인스턴스 멤버 사용하기
		Example obj = new Example(); // Example 클래스의 인스턴스 생성
		System.out.println("Instance variable : " + obj.instanceVariable);
	}
}

🤍 회고

오늘은 객체지향 프로그래밍의 핵심 개념인 클래스에 대해 다시 정리했다.
전체적으로 알고는 있었지만, 그동안은 명확히 의식하지 않고 사용해왔던 개념들이 많았다. 특히 클래스가 단순한 틀을 넘어서 설계의 중심이자 객체 간 책임을 나누는 핵심 구조라는 점을 다시 한 번 체감했다. 이전에 배웠던 내용이라도 막상 실무나 프로젝트에서 활용할 때는 놓치기 쉬운 부분이 많은 것 같다. 클래스를 의식하며 설계하고 사용하는 연습이 부족한 것 같아 클래스 구조를 더 신중히 설계해야겠다는 다짐을 하게 되었다.

profile
친애하는 개발자

0개의 댓글