활동/호기심

자바에서 클래스 멤버와 인스턴스 멤버.. 진짜 뭔소린지 하나도 모르겠네

ByeongJun 2023. 4. 9. 23:54
반응형

 

이번 게시물은 비전공자인 나의, 첫 코딩 선생님이었던 <생활코딩> 유튜브 채널을 보고 제작해 봤다. 

설명이 미흡할텐데 내 글 보다는 영상에서 직접 도움을 받길 바라며 어디 한번 열심히 정리해 보겠다.

 

 

 


클래스 맴버, 인스턴스 맴버 (1/4) : 맴버란?

멤버(member) 뜻이 '구성원'이라는 것은 누구나 알 것이다.

Java에서 객체에는 변수메소드라는 구성원이 있다.

 

package study;

class calculator {
	int left, right;

	public void setOprands (int left, int right) {
		this.left = left;            // [2] 입력값으로 전달한 값들을 인스턴스 변수로 지정 
		this.right = right;
	}

	public void sum() {
		System.out.println(this.left + this.right);
	}
}
public class study {
	public static void main(String[] args) {

        // [3] 맨처음에 c1, c2라는 인스턴스를 생성했다. 
        // 그리고 그 인스턴스 안에는 left, right라는 변수를 통해 값을 전달한다는 걸 알 수 있다. 
		
        calculator c1 = new calculator();   // [1] c1이라는 인스턴스 생성
		c1.setOprands(10,10);               // setOprands 메소드 호출해 10, 10을 인자로 전달
		c1.sum();
        
        calculator c2 = new calculator();   // [1] c2라는 인스턴스 생성
		c2.setOprands(20,20);               // setOprands 메소드 호출해 20, 20을 인자로 전달
		c2.sum();
	}
}

주석처리가 많아 지저분하긴 하지만 설명을 상세히 적어봤다. 

 

결론적으로 c1과 c2는 둘 다 left, right라는 변수를 갖고 있지만, 실제로 변수에 담겨있는 값은 다르다는 걸 알 수 있다. 

그러므로 left, right라는 변수는 인스턴스의 변수라고 할 수 있다. (인스턴스 마다 서로 다른 값을 넣으려고 하기 때문)

클래스 멤버의 변수는 위의 예제처럼 인스턴스 마다 값이 다른 것이 아니라 

모든 인스턴스에서 똑같은 값을 갖는다. 

 

인스턴스를 생성하지 않아도 클래스에 직접 접근해서 변수를 사용할 수 있다.

 

 

 


클래스 맴버, 인스턴스 맴버 (2/4) : 클래스 변수

모든 인스턴스가 공유할 수 있는 변수가 있다면 편리할 것이다. 

인스턴스는 각각 다른 값을 가졌지만, 바로 그 역할을 하는 것이 클래스 변수이다. 

 

class calculator {
	static double PI = 3.14;
	int left, right;

첫번째 강의에서 만들어놓은 left, right와 다르게 

PI 변수 앞에 static이라는 키워드가 붙었다. 

 

이 뜻은 바로, 이 변수는 클래스 소속이 된다는 의미이다.

그렇게 되면 저 변수를 모든 메소드에서 동일한 값으로 갖고 올 수 있게 된다. 

 

System.out.println(c1.PI);            // c1이라는 인스턴스를 통해 접근할 수도 있지만
System.out.println(Calculator.PI);    // 클래스를 통해 직접적으로도 접근 가능하다.

 

클래스 변수의 용도

  • 인스턴스에 따라 변하지 않는 값이 필요한 경우
  • 인스턴스를 생성할 필요가 없는 값을 클래스에 저장하고 싶은 경우
    (인스턴스 별로 다르게 셋팅되어있는 변수 값에 따른 다른 처리 결과를 얻고싶은 경우를 의미)
  • 값의 변경 사항을 모든 인스턴스가 공유해야 하는 경우

 

 

 


클래스 맴버, 인스턴스 맴버 (3/4) : 클래스 메소드

Calculator c1 = new Calculator();  // Calculator를 구체화 시킨 인스턴스를 생성
c1.setOprands(10,20);
c1.sum();                          // 인자 없이 호출한 sum, avg 메소드에
c1.avg();                          // 인스턴스 변수인 left, right에 저장된 변수에 값을 계산한 결과 출력

c1이라는 인스턴스를 new 연산자를 통해 생성하는 로직은 다른 상태를 갖고 있어야 하기 떄문에 

다시 말해, 서로 다른 c1, c2, c3.. 이런 식으로 결과가 다르게 출력될 경우 인스턴스를 생성한다는 것을 알 수 있다. 

 

클래스 메소드를 사용하면 메모리를 절약해 빠른 동작도 가능하다는 것을 알 수 있다. 

 

 

 


클래스 맴버, 인스턴스 맴버 (4/4) : 타입별 비교

  • 인스턴스 메소드는 클래스 멤버에 접근 할 수 있다.
  • 클래스 메소드는 인스턴스 멤버에 접근 할 수 없다. 

인스턴스 변수는 인스턴스가 만들어지면서 생성되는데, 클래스 메소드는 인스턴스가 생성되기 전에 만들어진다.

그렇기 때문에 클래스 메소드가 인스턴스 멤버에 접근하는 것은 존재하지 않는 인스턴스 변수에 접근하는 것과 같다.

 

 클래스가 만들어지고 나서 인스턴스 생성 가능 
인스턴스가 존재한다는 말은 클래스가 반드시 존재하고 있다는 뜻이다!
 

 

인스턴스 변수는 Non-Static Field, 클래스 변수는 Static Field라고 부르기도 한다.

(여기서 Field는 클래스 전역에서 접근할 수 있는 변수를 의미)

 

package Study;

	class C1{
	    static int static_variable = 1;						 // 클래스 변수
	    int instance_variable = 2;							 // 인스턴스 변수
	    static void static_static(){						 // 클래스 메소드가 클래스 변수를 호출
	        System.out.println(static_variable);
	    }
	    static void static_instance(){						 // 클래스 메소드에서 인스턴스 변수에 접근
	        // 클래스 메소드에서는 인스턴스 변수에 접근 할 수 없다. (컴파일 불가)
//	        System.out.println(instance_variable);
	    }
	    void instance_static(){
	        // 인스턴스 메소드에서는 클래스 변수에 접근 할 수 있다.
	        System.out.println(static_variable);
	    }
	    void instance_instance(){        
	        System.out.println(instance_variable);
	    }
	}
	public class ClassMemberDemo {  
	    public static void main(String[] args) {
	        C1 c = new C1();
	        // 인스턴스를 이용해서 정적 메소드에 접근 -> 성공
	        // 인스턴스 메소드가 정적 변수에 접근 -> 성공
	        
	        
	         c.static_static();
	        // 인스턴스를 이용해서 정적 메소드에 접근 -> 성공
	        // 정적 메소드가 인스턴스 변수에 접근 -> 실패
	        
	        
//	         c.static_instance();
	        // 인스턴스를 이용해서 인스턴스 메소드에 접근 -> 성공
	        // 인스턴스 메소드가 클래스 변수에 접근 -> 성공
	        
	        
//	         c.instance_static();
	        // 인스턴스를 이용해서 인스턴스 메소드에 접근 -> 성공 
	        // 인스턴스 메소드가 인스턴스 변수에 접근 -> 성공
	        
	        
//	         c.instance_instance();
	        // 클래스를 이용해서 클래스 메소드에 접근 -> 성공
	        // 클래스 메소드가 클래스 변수에 접근 -> 성공
	        
	        
	        // C1 클래스 접근
	        
//	         C1.static_static();
	        // 클래스를 이용해서 클래스 메소드에 접근 -> 성공
	        // 클래스에 소속되어 있는 메소드는 클래스를 통해 직접 접근 가능
	        // 클래스 메소드가 인스턴스 변수에 접근 -> 실패
	        
	        
//	         C1.static_instance();
	        // 클래스를 이용해서 인스턴스 메소드에 접근 -> 실패
	        
	        
//	        C1.instance_static();
	        // 아직 인스턴스는 생성되지 않았는데 인스턴스 메소드 접근하려고 하면 클래스는 접근 대상이 없기 때문
	        // 클래스를 이용해서 인스턴스 메소드에 접근 -> 실패

	        
//	        C1.instance_instance();
	        // 인스턴스 메소드 접근 불가 -> 실패
	    }
	}
반응형