유정잉

6일차 Java [ 싱글톤, Getter Setter, 정적 멤버, final, 패키지 ] 본문

네이버 클라우드 부트캠프/복습 정리

6일차 Java [ 싱글톤, Getter Setter, 정적 멤버, final, 패키지 ]

유정♡ 2024. 2. 27. 12:51

[ 정적 멤버 ] 

자바는 클래스 로더(loader)를 이용해서 클래스를 메소드 영역에 저장하고 사용한다. 정적(static) 멤버란 메소드 영역의 클래스를 고정적으로 위치하는 멤버를 말한다. 그래서 객체를 생성할 필요 없이 클래스를 통해 바로 사용이 가능하다. 

 

※ 정적 멤버 선언 : 필드와 메소드는 모두 정적 멤버가 될 수 있다. 정적 필드와 정적 메소드로 선언하려면 static 키워드를 추가하면 된다.

public class 클래스 {  
   static 타입 필드 [ = 초기값 ] ;   // 정적 필드 선언
   static 리턴 타입 메소드 ( 매개변수1, 매개변수2, ... ) { ... }  // 정적 메소드
}

 

객체마다 가지고 있을 필요성이 없는 공용적인 필드는 정적 필드로 선언하는 것이 좋다.  예를들어 Calculator 클래스에서 원의 넓이나 둘레를 구할 때 필요한 파이 는 Calculator 객체마다 가지고 있을 필요가 없기 때문에 정적 필드로 선언하는 것이 좋다.

public class Calculator {
    String color ;   //  계산기별로 색깔이 다를 수 있다.
    static double pi = 3.14159;  // 계산기에서 사용하는 파이 값은 동일하다.

 

인스턴스 필드를 이용하지 않는 메소드는 정적 메소드로 선언하는 것이 좋다. 예를 들어 Calculator의 plus() 메소드는 외부에서 주어진 매개값들을 가지고 처리하므로 정적 메소드로 선언하는 것이 좋다. (변경하는 값이 아니면 대부분 static 사용)

public class Calculator {
   String color ; 
   void setColor(String color) { this.color = color; }
   static int plus (int x, int y) { return x + y; }
   static int minus (int x, int y) { return x - y; }

 

※ 정적 멤버 사용 : 클래스가 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있는데, 클래스 이름과 함께 도트(.) 연산자로 접근하면 된다. ( 객체 필요 없이 클래스 명으로 바로 접근 가능 )

public class Calculator {
   static double pi = 3.14159;
   static int plus(int x, int y) { ... }
   static ont minus (int x, int y) { ... }

double result1 = 10*10*Calculator.pi;
int result2 = Calculator.plus(10,5);
int result3 = Calculator.minus(10,5);

 

※ 인스턴스 멤버 사용 불가 : 정적 메소드와 정적 블록은 객체가 없어도 실행된다는 특징 때문에 내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다. 객체 자신의 참조인 this도 사용할 수 없다.

인스턴스 멤버와 정적 멤버


 

[ final 필드와 상수 ]

인스턴스 필드와 정적 필드는 언제든지 값을 변경할 수 있다. 그러나 경우에 따라서는 값을 변경하는 것을 막고 읽기만 허용해야 할 때가 있다. 이때 final 필드와 상수를 선언해서 사용한다.

 

※ final 필드 선언 : final은 '최종적'이란 뜻을 가지고 있다. final 필드는 초기값이 저장되면 이것이 최종적인 값이 되어서 프로그램 실행 도중에 수정할 수 없게 된다. final 필드에 초기값을 줄 수 있는 방법은 두가지가 있다. 1) 필드 선언시에 초기값 대입 2) 생성자에서 초기값 대입. 고정된 값이라면 필드 선언 시에 주는 것이 제일 간단하다.

final 타입 필드 [ = 초기값 ] ;

 

※ 상수 선언 : 우리 주변에는 불변의 값이 있다. 불변의 값은 수학에서 사용되는 원주율 파이나 지구의 무게 및 둘레 등이 해당한다. 이런 불변의 값을 저장하는 필드를 자바에서는 상수 ( constant ) 라고 부른다. 상수는 객체마다 저장할 필요가 없고, 여러 개의 값을 가져도 안 되기 때문에 static 이면서 final인 특성을 가져야 한다. ( 초기값은 선언시에 주는 것이 일반적이지만, 복잡한 초기화가 필요한 경우에는 정적 블록에서 초기화할 수도 있다. 상수 이름은 대문자로 작성하는 것이 관례이다. 만약 서로 다른 단어가 혼합된 이름이라면 언더바(_)로 단어들을 연결한다. 또한 상수는 정적필드 이므로 클래스로 접근해서 읽을 수 있다. )

static final 타입 상수 [ = 초기값 ] ;

 

[ 패키지 ]

우리는 지금까지 장별, 절별 예제 클래스를 패키지 안에서 생성해서 관리했다. 자바의 패키지는 ( package ) 는 단순히 디렉토리만을 의미하지는 않는다. 패키지는 클래스의 일부분이며, 클래스를 식별하는 용도로 사용된다. 패키지는 주로 개발 회사의 도메인 이름의 역순으로 만든다. 예를들어 naver.com 회사의 패키지는 com.naver로 만든다. 이렇게 하면 여기서 개발한 Car 클래스가 있을 경우 다른 kr.co.google에서도 Car 클래스를 관리할 수 있다. 패키지는 상위 패키지와 하위 패키지를 도트(.)로 구분한다. 예를들어 com.naver는 com이 상위 디렉토리, naver가 하위 디렉토리.

※ 패키지 선언 : 패키지 디렉토리는 클래스를 컴파일 하는 과정에서 자동으로 생성된다. 컴파일러는 크랠스의 패키지선언을 보고 디렉토리를 자동 생성 시킨다. 패키지 선언은 package 키워드와 함께 패키지 이름을 기술한 것으로, 항상 소스 파일 최상단에 위치해야 한다. 패키지 이름은 모두 소문자로 작성하는 것이 관례이다.

package 상위패키지.하위캐피지 ;
public class 클래스명 { ... }

 

※ import 문 : 같은 패키지에 있는 클래스는 아무런 조건 없이 사용할 수 있지만, 다른 패키지 안에 있는 클래스를 사용하려면 import 문을 이용해서 어떤 패키지의 클래스를 사용하는지 명시해야 한다. import문이 작성되는 위치는 패키지 선언과 클래스 선언 사이다. 만약 동일한 패키지에 포함된 다수의 클래스를 사용해야 한다면 클래스 이름을 생략하고 *을 사용할 수도 있다.

package com.naver;   =>  Car클래스의 패키지
import kr.co.goolge;    =>   Tire클래스의 패키지
import kr.co.goolge.* ;   => 하위 클래스 모두를 가져오겠단 의미

public class Car {
   Tire tire = new Tire();   // 필드 선언 시 kr.co.google.Tire 클래스를 사용
}

 

※ import 문 자동 추가 기능 : ☆★ 단축키 Ctrl + Shift + O ☆★

 


[ Getter 와 Setter ] ☆★ ( 실무 多 )

객체의 필드 (데이터)를 외부에서 마음대로 읽고 변경할 경우 객체의 무결성(결점이 없는 성질)이 깨질 수 있다.

private 타입 fieldName;    => 필드 접근 제한자 : private

public 타입 getFieldName() {   = > 필드 접근 제한자 : public / 리턴타입 : 필드타입 /
                                                         메소드 이름 : get + 필드이름(첫 글자 대문자) / 리턴값 : 필드값
   return fieldName;
}

public void setFieldName(타입 fieldName) {  = > 필드 접근 제한자 : public / 리턴타입 : 필드타입 / 
                                                                메소드 이름 : get + 필드이름(첫 글자 대문자) / 리턴값 : 필드값
      this.fieldName = fieldName; 
}  

 

※ Getter / Setter 메소드 자동 생성  기능 : 필드를 선언한 후

                                                               ☆★  메뉴 -> Source -> Generate Getters and Setters 선택 ☆★


 

[ 싱글톤 패턴 ] ☆★ ( 실무 多 )

단 한개의 객체만 생성해서 사용하고 싶다면 싱글톤 ( Singleton ) 패턴을 적용할 수 있다. 싱글톤 패턴의 핵심은 생성자를 provate 접근 제한해서 외부에서 new 연산자로 생성자를 호출할 수 없도록 막는 것이다. (=>객체 생성을 못하도록 막아놈 )

private 클래스 () {}

 

생성자를 호출할 수 없으니 외부에서 마음대로 객체를 생성하는 것이 불가능해진다. 대신 싱글톤 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있다.

public  class 클래스 {
     private static 클래스 singleton = new 클래스 ();    // private 접근 권한을 갖는 정적 필드 선언과 초기화
     private 클래스 () {}    // private 접근 권한을 갖는 생성자 선언
     public static 클래스 getinstance() {  // public 접근 권한을 갖는 정적 메소드 선언
          return singlton;
   }
}
public class Singletone {
	private static Singletone singletone = new Singleton();   // private 접근 권한을 갖는 정적 필드 선언과 초기화
	                                                             => 자신의 singleton class 안에서 객체 생성 (외부생성 x)
	private Singleton() {  // private 접근 권한을 갖는 생성자 선언
	}
	
	public static Singleton getinstance() {  // public 접근 권한을 갖는 정적 메소드 선언 
                                          => 간접적으로 getinstance() 함수를 통해 singleton class가 막혔지만 쓸 수 있게 해줌
    
		return singleton;  // singleton 객체의 주소값 return
	}
}
public class SingletoneExample {

	public static void main(String[] args) {
		
//		Singleton obj1 = new Singletonnce();  => 컴파일 에러 위에서 private로 막아서 외부에서 접근 불가
//		Singleton obj1 = new Singletonnce();
		
		Singleton obj1 = Singleton.getInstance();  => 객체 못 만들어서 함수로 간접적으로 접근
		Singleton obj2 = Singleton.getInstance();  // 정적 메소드를 호출해서 싱글톤 객체 얻음
		
		if(obj1==obj2) {  // 동일한 객체를 참조하는지 확인
			System.out.println("같은 Singleton 객체입니다.");
		}else {
			System.out.println("다른 Singleton 객체입니다.");
		}
	}
		
}

  => 같은 singleton 객체입니다. 출력


 

[ 복습 응용 ]

클래스 메소드 복습 ( 0 ) / 빈 매개변수 하는 방법
클래스 메소드 복습 ( 1 )
클래스 메소드 복습 ( 2 )
클래스 메소드 복습 ( 3 )
클래스 메소드 복습 ( 4 )
클래스 메소드 복습 ( 5 )

 

클래스 메소드 복습 ( 6 )
클래스 메소드 복습 ( 7 )
클래스 메소드 복습 ( 8 )
이차원배열과  for문을 이용한 show 함수 구현 => 배열에 있는 총합 구해서 // 평균 출력하기
int ary [] {6,2,8,4,9}; 역순으로 출력하라.

 

 

Q. 다섯명의 학생의 점수를 입력하여 유효점수와 평균 출력하는 프로그램 유효점수는 최고점과 최저점을 제외한 점수이며 평균은 유효점수로 계산해라. (for-if문 중첩, contine사용)

실행결과) 5명 학생 점수 입력 : 1 2 3 4 5   /  유효 점수: 2 3 4   / 평균: 3.0

풀이) score[0]번째 값이 젤 큰 값이나 젤 작은 값이 아니여도 상관없는 이유 :
         만약 0번째가 10이라고 가정하면 socre[i] < 10 , score[i]가 맨처음값보다작으면 min이 그 값이 되는거기 때문에 // min=0으로 해버린다면 아무리 비교해도 항상 0이여서 안됨. / 둘다 최대,최소를잡아놓고 계속비교하는 것

728x90