하나의 클래스나 함수가 다양한 방식으로 동작 가능한 것.
오버로딩과 오버라이딩을 통해서 다형성 구현이 가능하다.
같은 메소드를 타입이나, 매개변수 갯수, 매개변수 타입을 다르게 해서 사용
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) { ... }
}
변수나 객체를 사용하기 전에 값을 할당하거나 초기 상태로 설정하는 과정을 말한다.
초기화는 안정적인 실행을 보장하는데 중요한 역할을 한다.
클래스 변수 : 클래스가 처음 로딩될때 단 한번 초기화 된다.
인스턴스 변수 : 인스턴스가 생성될 때마다 각 인스턴스 별로 초기화가 이루어진다.
클래스 변수
기본값 → 명시적 초기화(초기값 할당 int x = 10; 처럼) → 클래스 초기화 블록
인스턴스 변수
기본값 → 명시적 초기화 → 인스턴스 초기화 블록 → 생성자
정적(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);
}
}
오늘은 객체지향 프로그래밍의 핵심 개념인 클래스에 대해 다시 정리했다.
전체적으로 알고는 있었지만, 그동안은 명확히 의식하지 않고 사용해왔던 개념들이 많았다. 특히 클래스가 단순한 틀을 넘어서 설계의 중심이자 객체 간 책임을 나누는 핵심 구조라는 점을 다시 한 번 체감했다. 이전에 배웠던 내용이라도 막상 실무나 프로젝트에서 활용할 때는 놓치기 쉬운 부분이 많은 것 같다. 클래스를 의식하며 설계하고 사용하는 연습이 부족한 것 같아 클래스 구조를 더 신중히 설계해야겠다는 다짐을 하게 되었다.