[JAVA]클래스 맴버와 인스턴스

김주현·2021년 4월 1일
0

Java

목록 보기
9/15

클래스 변수

클래스변수는 모든 인스턴스가 공통된 값을 공유하는 변수이며, 인스턴스에 static을 붙여주면 됩니다. 한 클래스에 모든 인스턴스들이 공통적인 값을 가져야할 때 클래스 변수를 선언합니다.

인스턴스 변수

인스턴스 변수는 인스턴스가 생성될 때 생성됩니다. 인스턴스별로 다른값을 가질 수 있으므로 각각의 인스턴스마다 고유의 값을 가져야할때는 인스턴스를 선언해야 합니다.

클래스와 객체의 차이

클래스는 '설계도', 객체는 '설계도로 구현한 모든대상'을 의미합니다.

객체와 인스턴스의 차이

  • 클래스의 타입으로 선언되었을 때 객체라고 부르고, 그 객체가 메모리에 할당되어 사용할때 인스턴스라고 부릅니다.

  • 객체는 현실세계에 가깝고, 인스턴스는 소프트웨어 세계에 가깝습니다.

Calculator클래스에 PI변수정의

각각의 인스턴스마다 원주율값을 별도로 가질 필요가 없기 때문에 클래스 변수로 원주율값을 선언하였다.

class Calculator{
	//PI변수를 static한다 = 클래스의 소속이 된다.=모든 인스턴스에서 공유한다
	//즉, PI는 클래스변수이다.
	static double PI=3.14; 
	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 CalculatorDemo5 {
//인스턴스변수는 인스턴스마다 다른 변수를 갖게됨
//클래스변수는  모든 인스턴스가 공유하는 변수
	
	public static void main(String[] args) {
		Calculator c1=new Calculator();
		//모든 인스턴스가 그대로 사용하기 때문에 같은 값 3.14출력
		System.out.println(c1.PI);
		Calculator c2=new Calculator();
		System.out.println(c2.PI);
		//Calculator클래스를 통해서도 접근가능
		System.out.println(Calculator.PI);
		
	}

}

Calculator클래스에 base클래스 변수정의

클래스 변수 base값을 변경한 결과 모든 인스턴스의 base값이 변경됩니다.

class Calculator2{
	static double PI=3.14;
	//클래스 변수인 base가 추가됨
	static int base=0;
	int left,right;
	public void setOprands(int left, int right) {
		this.left=left;
		this.right=right;
	}
	public void sum() {
		//base추가
		System.out.println(this.left+this.right+base);
		
	}
	public void avg() {
		//base추가
		System.out.println((this.left+this.right+base)/2);
		
	}
}



public class CalculatorDemo2 {

	public static void main(String[] args) {
		//인스턴스변수 c1의 left값은 10이고 right값은 20이다.
		Calculator2 c1=new Calculator2();
		c1.setOprands(10, 20);
		//30출력
		c1.sum();
		//인스턴스변수 c2의 left값은 20이고 right값은 40이다.
		Calculator2 c2=new Calculator2();
		c2.setOprands(20, 40);
		//60출력
		c2.sum();
		//클래스 변수 base값을 10으로 지정함
		Calculator2.base=10;
		//40출력
		c1.sum();
		//70출력
		c2.sum();
	}

}

클래스 변수의 용도

  • 인스턴스에 따라서 변하지 않는 값이 필요한 경우 (위 예시에서의 클래스변수PI)
  • 인스턴스를 생성할 필요가 없는 값을 클래스에 저장하고 싶은 경우
  • 값의 변경사항을 모든 인스턴스가 공유해야 하는 경우

클래스 메소드

sum,avg를 꼭 같은 상태를 유지할 필요없이 인자를 지정하여 연산을 수행하는 경우라면 클래스메소드를 이용해 코드를 간소화할 수 있습니다.

class Calculator3{

	public static void sum(int left, int right) {
		System.out.println(left+right);
	}
	public static void avg(int i, int j) {
		System.out.println((left+right)/2);
		
	}
}




public class CalculatorDemo6 {	
	public static void main(String[] args) {
		//인스턴스없이 클래스 메소드 선언
		//굳이 인스턴스 left,right를 이용해서 값을 항상 유지해야할 필요는 없다
		//그래서 합계나 평균을 구할때마다 값을 서로 다르게 출력하는 식으로 계산할 수 있다.
		Calculator3.sum(10,20);
		Calculator3.avg(10,20);
		
		Calculator3.sum(20,40);
		Calculator3.avg(20,40);
		
	
	}

}

클래스 메소드의 원칙

  • 인스턴스 메소드는 클래스 맴버에 접근 할 수 있다.
  • 클래스 메소드는 인스턴스 맴버에 접근 할 수 없다.
    : 클래스가 먼저 생성되기 때문에 존재하지 않는 인스턴스 변수에 접근하는 것과 같다.
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) {
		//인스턴스 c생성
		C1 c=new C1();
		//인스턴스를 이용해서 정적 메소드에 접근 (O)
		//인스턴스 메소드가 정적변수에 접근(O)
		c.static_static();
		//인스턴스를 이용해서 정적 메소드에 접근(O)
		//정적 메소드가 인스턴스 변수에 접근(X)
		c.static_instance();
		//인스턴스를 이용해서 정적 메소드에 접근(O)
		//인스턴스 메소드가 정적변수에 접근(O)
		c.instance_static();
		//인스턴스를 이용해서 정적 메소드에 접근(O)
		//인스턴스 메소드가 정적변수에 접근(O)
		c.instance_instance();
		//클래스를 이용해서 인스턴스 메소드에 접근(X)
		C1.static_static();
		//클래스를 이용해서 인스턴스 메소드에 접근(X)
		C1.static_instance();
		//클래스가 먼저 생성되기 때문에 존재하지 않는 인스턴스 변수에 접근하는 것과 같다.
	}

}

예를 들어, 제품(인스턴스)는 공장(클래스)를 통해 나온 제품(인스턴스)이기에 제품의 생산데이터(클래스변수,클래스메소드)를 보고 싶으면 공장에 관련 자료를 요청 및 컴플레인을 통한 수정 및 확인이 가능합니다.
하지만 공장(클래스)는 생산하지도 않은 제품(인스턴스)의 실물 사진이나 실물 동영상을 확인할 수 없으니까 공장(클래스)는 제품의 정보(인스턴스 변수,인스턴스 메소드)에 접근 할 수 없습니다.

참고 : https://gmlwjd9405.github.io/2018/09/17/class-object-instance.html

1개의 댓글

comment-user-thumbnail
2021년 4월 22일

객체지향 어렵게 생각하지 마세요. 변수+함수 덩어리 다루는 것일 뿐입니다.

객체와 인스턴스 정의

1) 객체 = 클래스 변수
2) 인스턴스 = 메모리에 올라간 클래스 변수
결국 같은 말입니다.
! 클래스 안에 있는 변수를 클래스 변수라 표현하지 마세요. 그냥 객체 내 변수라고 하세요. 햇갈립니다.

클래스 변수를 만드는 방법은?

1) 내부 클래스 가지고 클래스 변수 선언
2) 외부 클래스 (추상클래스) 가지고 클래스 변수 선언

클래스 안에 들어가는 것들은?

1) 변수
2) 함수
3) 다른 클래스

객체와 공유변수

class A // 클래스
{
	static int valA;	// 얘는 메모리 한 공간에 두고, 객체 아무리 만들어도 그것만 쓰게함. 
	int valB; 		// 얘는 객체 만들 때 마다 메모리에 새 공간 추가.
	// etc
}

A testclassval1 = new A(); 	// 클래스 변수 = 객체 = 인스턴스

testclassval1.valA = 10; 	// 객체 내 변수 건들기. 객체 간 공유변수 건듬.
testclassval2.valA = 5;	// valA는 공유되니깐, 
print(testclassval1.valA)	// 5나옴. 객체 testclassval1의 valA가 바뀜.

testclassval1.valB = 10; 	// 객체 내 변수 건들기. 객체 마다 따로 만들어지는 변수 건듬.
testclassval2.valB = 5;	// valB는 공유 안되니깐,
print(testclassval1.valB)	// 10나옴. 객체 testclassval1의 valB는 그대로.

상단 두 개 예제의 차이는?

"Calculator클래스에 PI변수정의" 섹션과 "Calculator클래스에 base클래스 변수정의" 섹션의 차이는 그저,
클래스 내 공유변수를 상수용으로 쓰냐, 변수용으로 쓰냐 차이일 뿐이네요.

클래스 메소드의 원칙?

저 같으면 아래 처럼 정리합니다.

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) {
		
		// [1] 객체 쓰는 법. 클래스와new 사용.
		C1 c=new C1();		//인스턴스 c생성. 이 때, 공유용 변수, 함수 메모리에 올라감.

		c.static_static();		// 공유 변수 값 1 출력
		c.static_instance();		// 에러.
		c.instance_static();		// 공유 변수 값 1 출력
		c.instance_instance();	// 일반 변수 값 2 출력

		// [2] 클래스 이름 가지고 멤버 못건듦. 클래스 변수 선언해서 써야 함.
		C1.static_static();		// 에러
		C1.static_instance();		// 에러
	}
}
답글 달기