[Java] 클래스와 인스턴스 그리고 멤버

nemo·2022년 8월 16일
0

Java

목록 보기
3/4

클래스와 인스턴스

클래스는 객체의 설계도이다. 클래스에는 객체를 생성하기 위한 필드와 메서드가 정의되어 있다. 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스라고 한다.

// 설계도
class Calculator {
	int left, right;
    
    public void setOprands(int left, int right) {
    	// this는 새로 생성한 인스턴스(객체)를 가리킨다.
    	this.left = left;
        this.right = right;
    }

	public void sum() {
    	System.out.println(this.left + this.right);
    }
    
    public void avg() {
    	System.out.println((this.left + this.right) / 2);
    }
}

public class CalculatorDemo4 {
	
    public static void main(String[] args) {
    	
        // c1 변수의 데이터타입은 그 객체의 이름을 갖는다
        Calculator c1 = new Calculator(); // 인스턴스(객체) 생성
        c1.setOprands(10, 20); // 연산의 대상을 인자로 전달
        c1.sum();
        c1.avg();
    }
}

인스턴스 멤버와 정적 멤버

클래스에는 객체가 가져야 할 구성 멤버가 선언된다. 구성 멤버에는 필드, 생성자, 메서드가 있다. 이 구성 멤버들은 생략되거나 복수로 작성될 수 있다.

클래스는 객체의 설계도이다. 클래스 멤버(필드, 메서드)는 당연히 객체에도 포함되어 있어야 한다. 하지만 이것이 과연 효율적인지 생각해볼 필요가 있다.

클래스로부터 객체(인스턴스)는 하나가 아니라 여러 개가 만들어질 수 있다. 이 경우 클래스 멤버들을 객체마다 모두 가지고 있을 필요가 있을까?

객체마다 필드값이 달라야 한다면 해당 필드는 객체마다 가지고 있는 것이 맞다. 하지만 객체의 필드값이 모두 같아야 한다면 이 필드를 객체마다 가지고 있을 필요가 있을까? 만약 객체마다 갖고 있다면 메모리 낭비가 되며, 모든 객체의 필드 값을 같게 맞추는 추가적인 작업이 필요할 수도 있다. 오히려 이런 필드는 한 곳에 위치시키고 객체들이 공유하는 것이 좋을 수 있다.

자바는 이런 경우를 위해 클래스 멤버를 인스턴스 멤버와 정적 멤버로 구분해서 선언할 수 있도록 하고 있다. 인스턴스 멤버는 객체마다 가지고 있는 멤버를 말하고, 정적 멤버는 클래스에 위치시키고 객체들이 공유하는 멤버를 말한다.

정적 멤버

정적(static) 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메서드를 말한다. 각각 정적 필드, 정적 메서드라고 부른다.

// 설계도
class Calculator1 {
	// 클래스 변수 (클래스 멤버)이면서 정적 멤버 선언
	static double PI = 3.14;
    static int base = 0;
    
	int left, right;
    
    public void setOprands(int left, int right) {
    	this.left = left;
        this.right = right;
    }

	public void sum() {
    	System.out.println(this.left + this.right);
    }
    
    public void avg() {
    	System.out.println((this.left + this.right) / 2);
    }
}

public class CalculatorDemo {
	
    public static void main(String[] args) {
    	
        Calculator1 c1 = new Calculator1();
        System.out.println(c1.PI); // 3.14
        
        Calculator1 c2 = new Calculator1();
        System.out.println(c2.PI); // 3.14
        
        // 클래스를 통해서 직접 접근할 수도 있다.
        System.out.println(Calculator1.PI); // 3.14
    }
}

인스턴스 변수는 인스턴스마다 다른 값을 가지고 클래스 변수는 클래스의 변수이기 때문에 그 클래스를 통해 만들어진 모든 인스턴스들은 자연스럽게 그 클래스 변수를 그대로 가지고 있다.

// 설계도
class Calculator2 {
	// 클래스 변수 (클래스 멤버)
	static double PI = 3.14;
    static int base = 0;
    
	int left, right;
    
    public void setOprands(int left, int right) {
    	this.left = left;
        this.right = right;
    }

	public void sum() {
    	System.out.println(this.left + this.right + base);
    }
    
    public void avg() {
    	System.out.println((this.left + this.right + base) / 2);
    }
}

public class CalculatorDemo {
	
    public static void main(String[] args) {
    	
		Calculator2 c1 = new Calculator2();
        c1.setOprands(10, 20);
        // 30 출력
        c1.sum();
        
        Calculator2.base = 10;
        
        // 40 출력
		c1.sum();
    }
}

정적 메서드

각각의 객체마다 다른 값을 대입해서 출력해야 할 때에는 인스턴스를 생성하지만, 고정 값만 필요할 경우에는 정적 메서드를 사용한다.
인스턴스를 생성하지 않기 때문에 메모리 절약에 도움이 된다.

// 설계도
class Calculator3 {
	
	public static void sum(int left, int right) {
    	System.out.println(left + right);
    }
    
    public static void avg() {
    	System.out.println((left + right) / 2);
    }
}

public class CalculatorDemo {
	
    public static void main(String[] args) {
    	// 객체 생성 없이 클래스 메서드에 바로 접근 가능
		Calculator3.sum(10, 20);
        Calculator3.avg(10, 20);
    }
}

정적 메서드 선언 시 주의할 점
객체가 없어도 실행된다는 특징 때문에 정적 메서드를 선언할 때는 이들 내부에 인스턴스 필드나 인스턴스 메서드를 사용할 수 없다. 또한 객체 자신의 참조인 this 키워드도 사용이 불가하다. 컴파일 에러가 발생한다.



참고
혼자 공부하는 자바
생활코딩 자바

0개의 댓글