java
클래스 메서드와 인스턴스 메서드
- -
메서드(자바에서는 클래스 내의 함수를 칭함)의 목적은 코드를 간결하고 깔끔하게 정리하는 것이다.
여러 상태의 클래스가 동시에 필요할 때는 클래스 앞에 new를 붙여서 클래스의 복제본을 만들어서 서로 다른 상태를 유지할 수 있으며 dlr이것을 인스턴스(클래스의 복제본)라 부름
클래스의 변수를 바꾸면 모든 인스턴스의 변수의 값이 바뀜, 인스턴스 사용하는 클래스의 변수의 값을 바꿀 수 있는데 그렇게 하면 클래스 변수의 값이 변경되어 다른 인스턴스에서도 그 클래스 변수의 값이 변경됨
class Foo{
public static String classVar = "I class var";
public String instanceVar = "I instance var";
public static void classMethod() {
System.out.println(classVar); // Ok
// System.out.println(instanceVar); // Error
}
public void instanceMethod() {
System.out.println(classVar); // Ok
System.out.println(instanceVar); // Ok
}
}
public class StaticApp {
public static void main(String[] args) {
System.out.println(Foo.classVar); // OK
// System.out.println(Foo.instanceVar); // Error
Foo.classMethod();
// Foo.instanceMethod();
Foo f1 = new Foo();
Foo f2 = new Foo();
//
System.out.println(f1.classVar); // I class var
System.out.println(f1.instanceVar); // I instance var
//
f1.classVar = "changed by f1";
System.out.println(Foo.classVar); // changed by f1
System.out.println(f2.classVar); // changed by f1
// f1에서 클래스변수의 값을 바꾸었기에 그것을 참조하는 f2의 값도 바뀌게 됨
//
f1.instanceVar = "changed by f1";
System.out.println(f1.instanceVar); // changed by f1
System.out.println(f2.instanceVar); // I instance var
}
// 인스턴스 변수의 값을 바꾸었기에 f1과 다른 독립적인 변수를 운영하는 f2 인스턴스 변수의 값은 변경되지 않음
}
// 클래스의 static이없는 변수,메소드들은 인스턴스내에서 각각 독립적으로 새로 존재.
// 클래스의 static이있는 변수,메소드들은 인스턴스내에서 존재한다기보단 class의 존재하는것들을 가리킴(연결됨)
클래스 메서드: 클래스 변수와 인스턴스 변수와 비슷하게 메서드 앞에 static의 유뮤로 클래스 메서드/인스턴스 메서드로 갈리게 된다. 클래스 메서도 클래스 변수처럼 객체를 생성하지 않고 호출이 가능하지만, 인스턴스 메서드는 객체를 생성해야만 호출이 가능하다.
- 클래스 만들 때 멤버 변수중에서 모든 인스턴스에 공통으로 사용되는 것에 static을 붙임 (생성된 각 인스턴스는 서로 독립적 > 각 인스턴스 변수는 서로 다른 값을 가짐 but 모든 인스턴스에서 같은 값이 유지되어야 하는 변수는 static을 붙여 클래스 변수로 지정)
- 클래스 메서드는 인스턴스 변수를 사용할 수 없다. (인스턴스 변수는 인스턴스가 있어야 사용 가능한데, 클래스 메서드는 인스턴스 생성 없이 호출 가능하므로 클래스 메서드가 호출되었을 때 인스턴스가 없을수도 있음 > 클래스 매서드에서 인스턴스 변수의 사용을 금지함 but 인스턴스 변수/메서드에서는 static이 붙은 멤버들을 사용하는것이 가능. 인스턴스 변수가 존재한다는 것은 static변수가 이미 메모리에 존재한다는 것을 의미함 )
- 메서드 내에서 인스턴스 변수를 사용하지 않으면 static을 붙이는 것을 고려 (메서드의 작업 내용중 인스턴스 변수를 사용하면 static 사용 불가능, 인스턴스 변수를 사용하지 않으면 static을 붙이는게 메서드 호출 시간이 짧아져 성능 향상에 좋음 )
- static을 안붙인 메서드는 실행시 호출할때 찾는 과정이 추가적으로 필요해서 시간이 더 오래 걸림
class MyMathRe {
long a, b;
// 인스턴스변수 a, b만을 이용해서 작업하므로 매개변수가 필요없다.
long add() { return a + b; } // a, b는 인스턴스변수
long multiply() { return a * b; }
double divide() { return a / b; }
// 인스턴스변수와 관계없이 매개변수만으로 작업이 가능하다.
static long add(long a, long b) { return a + b; } // a, b는 지역변수
static long multiply(long a, long b) { return a * b; }
static double divide(double a, double b) { return a / b; }
}
class MyMathTestRe2 {
public static void main(String args[]) {
// 클래스메서드 호출. 인스턴스 생성없이 호출가능
System.out.println(MyMathRe.add(200L, 100L));
System.out.println(MyMathRe.multiply(200L, 100L));
System.out.println(MyMathRe.divide(200.0, 100.0));
MyMathRe mm = new MyMathRe(); // 인스턴스를 생성
mm.a = 200L;
mm.b = 100L;
// 인스턴스메서드는 객체생성 후에만 호출이 가능함.
System.out.println(mm.add());
System.out.println(mm.multiply());
System.out.println(mm.divide());
}
}
- 같은 클래스에 속한 멤버들 간에는 별도의 인스턴스 생성 없이 서로 참조/호출 가능 but 클래스 멤버가 인스턴스 멤버를 참조/호출 할 때는 인스턴스를 생성해야함 (인스턴스 멤버가 존재하는 시점에는 클래스 멤버는 항상 존재하지만, 클래스 멤버가 존재하는 시점에선 인스턴스 멤버가 존재하지 않을수도 있기 때문)
class Example{
void instanceMethod(){} // 인스턴스 메서드
static void staticMethod(){} // static 메서드
void instanceMethod2(){ // 인스턴스 메서드
instanceMethod(); // 다른 인스턴스메서드를 호출한다.
staticMethod(); // static 메서드를 호출한다.
}
static void staticMethod2(){ // static 메서드
instanceMethod(); // 에러!(불가능) 인스턴스 메서드 호출 불가능
staticMethod(); // static 메서드는 호출 할 수 있다.
}
}
- 인스턴스 메서드는 인스턴스 변수를 사용할 수 있지만(당연한 말...) static 메서드는 인스턴스 변수 사용 불가
class MemberCall1 {
int iv = 10;
static int cv = 20;
int iv2 = cv;
// static int cv2 = iv; // 에러. 클래스변수는 인스턴스 변수를 사용할 수 없음.
static int cv2 = new MemberCall1().iv; // 이처럼 객체를 생성해야 사용가능.
static void staticMethod1() {
System.out.println(cv);
// System.out.println(iv); // 에러. 클래스메서드에서 인스턴스변수를 사용불가.
MemberCall1 c = new MemberCall1();
System.out.println(c.iv); // 객체를 생성한 후에야 인스턴스변수의 참조가능.
}
void instanceMethod1() {
System.out.println(cv);
System.out.println(iv); // 인스턴스메서드에서는 인스턴스변수를 바로 사용가능.
}
static void staticMethod2() {
staticMethod1();
// instanceMethod1(); // 에러. 클래스메서드에서는 인스턴스메서드를 호출할 수 없음.
MemberCall1 c = new MemberCall1();
c.instanceMethod1(); // 인스턴스를 생성한 후에야 호출할 수 있음.
}
void instanceMethod2() { // 인스턴스메서드에서는 인스턴스메서드와 클래스메서드
staticMethod1(); // 모두 인스턴스 생성없이 바로 호출이 가능하다.
instanceMethod1();
}
}
- 중요: <클래스 멤버가 인스턴스 멤버를 참조하기 위해선 객체를 생성해야 함!!> <쉽게 말해 클래스 메서드로 사용되면 클래스에서 메서드 선언시 static을 붙이고 인스턴스 메서드로 사용되면 static을 붙이지 않음>
- 인스턴스 멤버간 호출에는 아무 문제 X > 하나의 인스턴스 멤버가 존재한다는 것은 인스턴스가 이미 생성되었단 것을 의미, 다시 말해 다른 인스턴스 멤버도 모두 존재하기 때문
+
class Accounting{
// valueOfSupply, getVAT(), getTotal()는 인스턴스와 관련있기에 static 사용하지 않는다.
public double valueOfSupply;
public static double vatRate = 0.1;
public Accounting(double valueOfSupply) {
// 생성자 작성시 실행동작이 필요하다면 생성자 함수도 정의한다.
this.valueOfSupply = valueOfSupply;
//왼쪽은 this를 통해 인스턴스의 변수를 가리키고 오른쪽은 바로 위의 매개변수를 뜻한다.
}
public double getVAT() {
return valueOfSupply * vatRate;
}
public double getTotal() {
return valueOfSupply + getVAT();
}
}
public class AccountingApp {
public static void main(String[] args) {
Accounting a1 = new Accounting(10000.0);
Accounting a2 = new Accounting(20000.0);
System.out.println("Value of supply : " + a1.valueOfSupply);
System.out.println("Value of supply : " + a2.valueOfSupply);
System.out.println("VAT : " + a1.getVAT());
System.out.println("VAT : " + a2.getVAT());
System.out.println("Total : " + a1.getTotal());
System.out.println("Total : " + a2.getTotal());
}
}
'java' 카테고리의 다른 글
생성자와 this (기초개념) (0) | 2023.01.08 |
---|---|
Exception (0) | 2022.12.22 |
함수의 타입(추가 예정) (0) | 2022.12.22 |
변수 선언에 관련하여 (0) | 2022.12.20 |
이클립스 없이 내부적으로 자바 실행하기 (Mac, 터미널) (0) | 2022.12.19 |
Contents
소중한 공감 감사합니다