관리 메뉴

나구리의 개발공부기록

자바의 정석 기초편 ch6 - 26 ~ 31[static메서드와 인스턴스 메서드, 오버로딩] 본문

유튜브 공부/JAVA의 정석 기초편(유튜브)

자바의 정석 기초편 ch6 - 26 ~ 31[static메서드와 인스턴스 메서드, 오버로딩]

소소한나구리 2023. 11. 17. 16:06

1) 인스턴스 메서드

  • 인스턴스 생성 후 '참조변수.메서드이름()'으로 호출 
  • 인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드
  • 메서드 내에서 인스턴스 변수(iv)에 접근하여 사용할 수 있음
  • 인스턴스 변수만 사용할 수 있는 것은 아니며 매개변수를 작성하면 지역변수도 활용하여 메서드의 코드를 작성할 수 있음
  • 인스턴스 메서드 호출 시 객체 생성이 꼭 필요함
    • 객체 = iv의 묶음
    • iv = 변수를 묶어 놓은 것

2) Static 메서드(클래스 메서드)

  • 객체 생성 없이 '클래스이름.메서드이름()'으로 호출
  • Math.random() - Math 클래스의 random메서드 호출, Math.round() 의 예시가 있음
  • 인스턴스 멤버(Iv,im)와 관련없는 작업을 하는 메서드
  • static 메서드 내에서 인스턴스 변수(iv)를 직접 사용 불가
  • 작업에 필요한 값을 매개변수로 작성하여 호출시 인자로 받기 때문에 iv값을 사용할 필요가 없음

3) 인스턴스메서드와 static 메서드는 서로 반대

  • iv(인스턴스변수) 사용유무의 차이가 있음
  • 인스턴스 변수를 사용할 수 있으면 인스턴스 메서드
  • 사용하지 않으면 static메서드
class MyMath2 {
	long a, b;	//iv(인스턴스 변수) -> 클래스 전체에서 사용할 수 있음
	
	//인스턴스 메서드(iv를 사용) = 클래스 전체에서 사용 가능함
	long add() {	 
		return a + b;	//iv
	}
	
	//클래스 메서드(static매서드)(iv를 사용하지 않음)
	static long add(long a, long b) {
	//(long a,long b) = lv(지역변수)
	// lv의 유효범위 - 선언된 위치부터 메서드 종료까지만 유효	
		return a + b;	//lv
	} 
}

// 클래스 호출
class ex6_9 {
	public static void main(String args[]) { 
		//클래스(static)메서드 호출(클래스이름.메서드이름)
		//객체 생성 없이 호출 가능(실행 됨)
		System.out.println(MyMath2.add(200L,100L));
		
		// 인스턴스 메서드 호출 순서
		MyMath2 mm = new MyMath2() ;	//1.객체(인스턴스) 생성 = iv생성
		mm.a = 200L;	//iv
		mm.b = 100L;	//iv
		// 2.인스턴스 메서드 호출(참조변수.메서드이름) = iv로 작업
		System.out.println(mm.add());
	}
}

4) static을 언제 붙여야 할까?

(1) 멤버변수(속성)

  • 속성 중에서 공통 속성에 static을 붙이고 개별속성은 인스턴스 변수로 활용
  • 개별 속성 -> iv
  • 공통 속성  -> cv 클래스 변수(static 붙힘)

(2) 메서드(명령문의 집합)

  • 인스턴스 멤버(iv, im)을 사용하지 않는 메서드에 static을 붙힘
class MyMath2 {
	long a, b;	// iv
    
	long add() { return a + b; } // a,b는 인스턴스변수(iv) 
	static  long add(long a, long b) { return a + b; } // a, b는 지역변수(lv)

 

(3) 메서드 간의 호출과 참조

  • static 메서드는 인스턴스 변수(iv)를 직접적으로 사용할 수 없음
class TestClass2 {
	int iv;	//인스턴스 변수 -> 객체를 생성 후 사용 가능
	static int cv;	// 클래스 변수 -> 언제나 사용가능
	
	void instanceMethod() {	// 인스턴스 메서드 -> 객체 생성 후 호출 가능
		System.out.println(iv);	// 인스턴스 변수를 사용 가능
		System.out.println(cv);	// 클래스 변수를 사용 가능
	}
	
	static void staticMethod() {	// static 메서드 -> 객체 생성 없이 항상 호출 가능
		// iv는 객체를 생성해야 호출이 가능함
		System.out.println(iv);	// 에러 발생! - 인스턴스 변수 사용 불가
		System.out.println(cv);	// 클래스 변수 사용 가능
	}
} // class 종료
  • static 메서드는 인스턴스 메서드(im)를 직접적으로 호출할 수 없다
// static 메서드는 인스턴스 메서드(im)를 호출할 수 없다
class TestClass {
	void instanceMethod() {}	// 인스턴스 메서드 -> 객체 생성 후 호출 가능
	static void staticMethod() {}	// static 메서드 -> 객체 생성 없이 항상 호출 가능
	
	void instanceMethod2() {	// 인스턴스 메서드
		instanceMethod();	// 다른 인스턴스메서드를 호출 가능
		staticMethod();		// static메서드를 호출 가능(항상 ok)
	}
	static void staticMethod2() {	// static메서드
		// 객체를 생성하면 사용 가능
		instanceMethod();	// 에러!! iv를 사용하는 메서드를 호출할 수 없다
		staticMethod();		// static메서드 호출 가능
	}
} //class 종료

 

(4) 정리

  • static 메서드는 static 메서드 호출 가능한가? -> 가능
  • static 메서드는 인스턴스 변수 사용 가능? -> 직접사용 불가능, 인스턴트 변수는 객체를 사용 해야만 사용 가능함
  • static 메서드는 인스턴스 메서드 호출 가능? -> 직접사용 불가능, 위와 동일
  • 왜 static 메서드는 인스턴스 멤버(Iv,im) 사용이 불가능 한가? -> static 메서드 호출 시(항상 사용가능) 객체(iv)가 없을 수도 있기 때문, 즉 객체를 생성하여 참조변수로 인스턴스 멤버를 사용하면 static 메서드에서도 사용 가능함

5) 오버로딩(메서드)

  • 한 클래스 안에 같은 이름의 메서드를 여러개 정의 하는 것
  • 원래는 메서드와 메서드 이름이 1대1로 정의되어야 하지만 오버로딩을 사용하면 같은 기능을 하는 메서드의 이름을 같게 작성해도 됨

(1) 대표적인 오버로딩 예시 - println()

  • 만약 오버로딩이 지원 되지 않는다면 메서드이름도 printlnInt, printlnStr 등으로 따로따로 정의 해야함.

 

(2) 오버로딩의 조건

  • 메서드 이름이 같아야 함
  • 매개변수의 개수나 타입이 달라야 함
  • 반환 타입은 영향이 없음
// 매개변수의 개수와 변수타입이 같음 -> 오버로딩이 아님
// 메서드 중복정의 에러 -> add(int,int) is already defined
int add (int a, int b) { return a+b };
int add (int a, int b) { return a+b };

// 반환타입은 영향이 없음 -> 오버로딩이 아님
// 위와 같은 에러 발생
int add (int a, int b) { return a+b };
long add (int a, int b) { return a+b };

// 매개변수의 개수는 같지만 변수의 타입이 다름 -> 오버로딩 OK
int add (int a, long b) { return a+b };
long add (long a, int b) { return a+b };

위 상황에서 조심해야하는 상황
add(3,3) // 호출 -> 에러발생(컴파일러가 1,2번 중 어떤걸 사용해야할지 모호하게 됨(ambiguous)
add(3,3L) // 1번째 호출 OK

 

(3) 예제

  • 메서드 오버로딩 기능을 활용하여 add()라는 이름으로 여러개의 메서드를 정의
  • 각 메서드의 매개변수의 타입이나 개수를 다르게 하여 정의된 메서드의 기능이 모두 동일한 기능을 하지만 여러 타입을 입력받을 수 있도록하여 프로그램을 유연하게 설계할 수 있음
class ex6_10 {
    public static void main(String args[]) {
        MyMath3 mm = new MyMath3();
        System.out.println("mm.add(3, 3) 결과: "   + mm.add(3,3));
        System.out.println("mm.add(3L, 3) 결과: "  + mm.add(3L,3));
        System.out.println("mm.add(3, 3L) 결과: "  + mm.add(3,3L));
        System.out.println("mm.add(3L, 3L) 결과: " + mm.add(3L,3L));

        int[] a = {100, 200, 300};
        System.out.println("mm.add(a) 결과: " + mm.add(a));
   }
}

class MyMath3 {
    int add(int a, int b) {
        System.out.print("int add(int a, int b) - ");
        return a+b;
    }
		
    long add(int a, long b) {
        System.out.print("long add(int a, long b) - ");
        return a+b;
    }
		
    long add(long a, int b) {
        System.out.print("long add(long a, int b) - ");
        return a+b;
    }

    long add(long a, long b) {
        System.out.print("long add(long a, long b) - ");
        return a+b;
    }

    int add(int[] a) {		// 배열의 모든 요소의 합을 결과로 돌려준다.
        System.out.print("int add(int[] a) - ");
        int result = 0;
        for(int i=0; i < a.length;i++) 
            result += a[i];
			
        return result;
    }
}
    
출력결과

int add(int a, int b) - mm.add(3, 3) 결과:6
long add(long a, int b) - mm.add(3L, 3) 결과: 6
long add(int a, long b) - mm.add(3, 3L) 결과: 6
long add(long a, long b) - mm.add(3L, 3L) 결과: 6
int add(int[] a) - mm.add(a) 결과: 600

 

** 출처 : 남궁성의 정석코딩_자바의정석