Java

[Java] 생활코딩 | 클래스 멤버, 인스턴스 멤버, 클래스 메소드, 유효범위

kyra 2022. 11. 13. 13:11

https://youtu.be/o73qn218VjM


package org.opentutorials.javatutorials.classninstance;
 
class Calculator {
    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 CalculatorDemo1 {
 
    public static void main(String[] args) {
 
        Calculator c1 = new Calculator();
        System.out.println(c1.PI); //3.14 출력
 
        Calculator c2 = new Calculator();
        System.out.println(c2.PI);  //3.14 출력
 
        System.out.println(Calculator.PI);  //3.14 출력
 
    }
 
}

1. 멤버 변수 : 클래스 내에 메소드 밖에 선언된 변수, 객체변수/ 클래스변수/ 종단변수가 있다.

 

 1) 클래스변수 : 각각의 객체에서 동일한 값을 사용하고자 할 때 지정

* static을 멤버(변수, 메소드)앞에 붙이면 클래스 멤버가 된다.

* 사용하는 경우

 - 객체에 따라서 변하지 않는 값이 필요한 경우 (사실  final을 이용해서 상수로 선언하는것이 바람직함)

 - 객체를 생성할 필요가 없는 값을 클래스에 지정하고 싶은 경우

 - 값의 변경 사항을 모든 인스턴스가 공유하는 경우

 

2. 클래스 메소드 (static을 앞에 붙인다)

package org.opentutorials.javatutorials.classninstance;
 
class Calculator3{
  
    public static void sum(int left, int right){
        System.out.println(left+right);
    }
     
    public static void avg(int left, int right){
        System.out.println((left+right)/2);
    }
}
 
public class CalculatorDemo3 {
     
    public static void main(String[] args) {
        Calculator3.sum(10, 20); //클래스 변수를 사용하지 않고 직접 클래스에 접근한다.
        Calculator3.avg(10, 20);
         
        Calculator3.sum(20, 40);
        Calculator3.avg(20, 40);
    }
 
}

 

* 클래스 메소드 : 클래스 변수를 사용하지 않고 직접 클래스에 접근한다.

* 필요할 때마다 변수를 다르게 하고 싶을 때 굳이 객체를 생성하지 않고 클래스에 직접 접근한다.

 

* 원칙

 1) 인스턴스 메소드(static이 없는 메소드)는 클래스 멤버에 접근할 수 있다.

   + 인스턴스가 있다는 것은 이미 클래스가 있다는 의미. 따라서 클래스 멤버에 접근 가능하다.

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

   + 클래스는 항상 먼저 만들어지게 된다. 따라서 아직 생성되지 않은 인스턴스의 멤버에 접근할 수 없다.

 

package org.opentutorials.javatutorials.classninstance;
 
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.static_static(); //클래스에 직접 접근
        // 클래스를 이용해서 클래스 메소드에 접근 -> 성공
        // 클래스 메소드가 인스턴스 변수에 접근 -> 실패
        C1.static_instance();
        // 클래스를 이용해서 인스턴스 메소드에 접근 -> 실패
        //C1.instance_static();
        // 클래스를 이용해서 인스턴스 메소드에 접근 -> 실패
        //C1.instance_instance();
    }
 
}

유효 범위(Scope)

- 클래스 아래에서 선언된 변수는 클래스 전역에 영향을 미침

- 메소드 내에서 선언된 변수는 클래스 아래 선언된 변수보다 우선순위가 높다. (메소드 안에서만 사용 가능하다.)

 

import java.util.*;
import java.lang.*;
import java.io.*;
 
class ScopeDemo6 {
    static int i = 5;

	static void a() {
		int i = 10; //2. 메소드 a의 지역변수 i는 10, 그리고 b메소드를 실행
		b();
	}

	static void b() {
		System.out.println(i); //3. b메소드는 i를 출력하는데 이때 i는 전역변수 i, 따라서 5 출력
	}

	public static void main(String[] args) {
		a(); //1. a를 출력하므로 메소드 a로 이동
	}

}

//5를 출력
import java.util.*;
import java.lang.*;
import java.io.*;
 
class ScopeDemo6 {
    static int i = 5;

	static void a() {
		int i = 10; //2. 메소드 a의 지역변수 i는 10, 그리고 b메소드를 실행
		b();
	}

	static void b() {
    	int i = 20;
		System.out.println(i); //3. b메소드는 i를 출력하는데 이때 i는 메소드 b안의 지역변수 i, 따라서 20 출력
	}

	public static void main(String[] args) {
		a(); //1. a를 출력하므로 메소드 a로 이동
	}

}

//5를 출력

this : 인스턴스 자신을 의미하는 객체

 

package org.opentutorials.javatutorials.scope;
 
class C3 {
    int v = 10;
 
    void m() {
        int v = 20;
        System.out.println(this.v); //메소드 m의 지역변수 v(20)이 아닌 객체변수 v(10)이 출력
    }
}
 
public class ScopeDemo9 {
 
    public static void main(String[] args) {
        C3 c1 = new C3();
        c1.m();
    }
 
}