클래스변수는 모든 인스턴스가 공통된 값을 공유하는 변수이며, 인스턴스에 static을 붙여주면 됩니다. 한 클래스에 모든 인스턴스들이 공통적인 값을 가져야할 때 클래스 변수를 선언합니다.
인스턴스 변수는 인스턴스가 생성될 때 생성됩니다. 인스턴스별로 다른값을 가질 수 있으므로 각각의 인스턴스마다 고유의 값을 가져야할때는 인스턴스를 선언해야 합니다.
클래스는 '설계도', 객체는 '설계도로 구현한 모든대상'을 의미합니다.
클래스의 타입으로 선언되었을 때 객체라고 부르고, 그 객체가 메모리에 할당되어 사용할때 인스턴스라고 부릅니다.
객체는 현실세계에 가깝고, 인스턴스는 소프트웨어 세계에 가깝습니다.
각각의 인스턴스마다 원주율값을 별도로 가질 필요가 없기 때문에 클래스 변수로 원주율값을 선언하였다.
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);
}
}
클래스 변수 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();
}
}
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) 객체 = 클래스 변수
2) 인스턴스 = 메모리에 올라간 클래스 변수
결국 같은 말입니다.
! 클래스 안에 있는 변수를 클래스 변수라 표현하지 마세요. 그냥 객체 내 변수라고 하세요. 햇갈립니다.
클래스 변수를 만드는 방법은?
1) 내부 클래스 가지고 클래스 변수 선언
2) 외부 클래스 (추상클래스) 가지고 클래스 변수 선언
클래스 안에 들어가는 것들은?
1) 변수
2) 함수
3) 다른 클래스
객체와 공유변수
상단 두 개 예제의 차이는?
"Calculator클래스에 PI변수정의" 섹션과 "Calculator클래스에 base클래스 변수정의" 섹션의 차이는 그저,
클래스 내 공유변수를 상수용으로 쓰냐, 변수용으로 쓰냐 차이일 뿐이네요.
클래스 메소드의 원칙?
저 같으면 아래 처럼 정리합니다.