패키지와 접근 제한자, Getter, Setter

이동주·2025년 3월 6일

JAVA

목록 보기
16/30

패키지

  • 클래스명을 식별하는 용도로 사용! (클래스명의 일부)
  • 클래스명의 중복을 막기 위해 사용되는 것으로 방(폴더)의 개념으로 사용!
  • 클래스명의 풀네임은 패키지.클래스명
  • 패키지명은 주로 개발 회사의 도메인 이름의 역순으로 만들고, 마지막에는 프로젝트명!
  • 상위 패키지와 하위 패키지를 도트(.)로 구분함
  • 같은 이름의 클래스명이더라도 적혀져있는 패키지명이 다르면 오류가 남! 따라서 클래스가 위치해있는 해당 패키지명으로 이름을 바꿔줘야함
  • 풀네임 : 패키지명.클래스명
  • 패키지명은 모두 소문자로 작성하기! (카멜 표기법 x)

import

  • 다른 패키지에 있는 클래스를 사용하기 위해 사용하는 구문

  • import문을 이용하여 사용하고자 하는 패키지명을 선언하면 해당 패키지의 클래스를 사용할 수 있음

  • import문은 패키지 선언과 클래스 선언 사이에 작성!

  • import문을 사용하지 않을 경우에는 클래스를 선언할 때 풀네임을 써줘야함

  • 해당 패키지의 모든 클래스를 다 쓰는 방법 : *

  • 자동으로 import를 선언하는 방법 : Ctrl + shift + o
    -> 클래스명이 중복되는 경우 클래스를 선택할 수 있는 창이 뜸! 거기서 선택

package ch06.sec12.hyundai;
// 패키지 : 클래스명을 식별하기 위해 있는 것

import ch06.sec12.hankook.SnowTire;
import ch06.sec12.kumho.AllSeasonTire;
// import : 다른 패키지의 클래스를 사용하고자 할 때 사용!

public class Car {
	ch06.sec12.hankook.Tire tire1 = new ch06.sec12.hankook.Tire();
	ch06.sec12.kumho.Tire tire2 = new ch06.sec12.kumho.Tire();
	// 위와 같이 import문을 선언하지 않고 다른 패키지의 클래스를 사용하기 위해서는
	// 패키지명과 클래스명을 합친 풀네임을 선언해줘야함
	
	SnowTire tire3 = new SnowTire();
	AllSeasonTire tire4 = new AllSeasonTire();
	// 위의 두 구문은 import문을 선언하였기 때문에 클래스명만 선언함
	// import문 자동 생성 : ctrl + shift + o
}

접근 제한자

  • 중요한 필드와 메소드가 외부로 노출되지 않도록 해 객체의 무결성을 유지하기 위해 접근 제한자 사용

클래스의 접근 제한

  • 종류
    1. public : 제한 범위가 없음 (제한 대상 : 클래스, 필드, 생성자, 필드)
      -> 클래스를 선언할 때 public 접근 제한자를 붙이면 클래스는 다른 패키지에서도 사용 가능
      -> 클래스를 선언할 때 public 접근 제한자를 생략하면 클래스는 다른 패키지에서 사용할 수 없음
    2. protected : 같은 패키지자식 객체만 사용 가능 (상속 관계에서만 사용)
      -> 제한 대상 : 필드, 생성자, 메소드
    3. (default)(아무것도 없음) : 같은 패키지에서만 사용 가능
      -> 제한 대상 : 클래스, 필드, 생성자, 메소드
    4. private : 객체 내부에서만 사용 가능하며 주로 필드에서만 사용함!
      -> 제한 대상 : 필드, 생성자, 메소드
  • default 접근 제한을 사용한 A 클래스
package ch06.sec13.exam01.package1;

class A { 
	// default 접근 제한 사용
}
  • public 접근 제한을 사용하며 A와 같은 패키지를 사용한 B 클래스
package ch06.sec13.exam01.package1;
// A클래스와 같은 패키지

public class B {
	A a; 
	// A 클래스는 default 접근 제한을 걸었기 때문에 
	// 같은 패키지 안에 있는 B 클래스에서는 접근 가능
}
  • A, B와 다른 패키지를 사용한 C 클래스
package ch06.sec13.exam01.package2;
// A, B 클래스와 다른 패키지
import ch06.sec13.exam01.package1.*;
// import를 사용하여 package1의 클래스들을 모두 불러옴


public class C {
	// A a;
	// C 클래스는 A 클래스와 다른 패키지에 만들어져있고
	// A 클래스는 default로 접근 제한을 걸어놨기 때문에
	// C 클래스에서는 접근 불가
	
	B b;
	// B 클래스는 A 클래스와 같은 패키지에 만들어졌지만
	// public으로 접근 제한을 걸어놨기 때문에
	// import를 선언해주면 다른 패키지에서도 사용 가능함
}

생성자의 접근 제한

  • 종류
  1. public : 모든 패키지에서 생성자를 호출할 수 있음
    -> 생성자는 공유의 개념을 가지기 때문에 public을 제일 많이 사용함
  2. (default) : 같은 패키지에서만 생성자를 호출할 수 있음
  3. private : 클래스 내부에서만 생성자를 호출할 수 있음

필드와 메소드의 접근 제한

  • 종류
  1. public : 모든 패키지에서 필드를 읽고 변경 가능하며, 메소드를 호출할 수 있음
    -> 메소드는 공유의 개념을 가지기 때문에 public을 제일 많이 사용함
  2. (default) : 같은 패키지에서만 필드를 읽고 변경 가능하며, 메소드를 호출할 수 있음
  3. private : 클래스 내부에서만 필드를 읽고 변경 가능하며, 메소드를 호출할 수 있음
    -> 외부에서 필드의 값을 임의로 변경할 수 있기에 필드에서 주로 사용!

Setter, Getter

Setter

  • 데이터를 검증해서 유효한 값만 필드에 저장하는 메소드
  • private 형태의 필드값을 설정하는 역할

Getter

  • 필드값이 객체 외부에서 사용하기에 부적절한 경우, 적절한 값으로 변환해서 리턴할 수 있는 메소드
  • setter로 private 형태의 필드값을 설정하면 이를 읽는 역할
  • boolean 타입은 get메소드명이 아닌 is메소드명!

Setter, Getter 자동 생성

  • 해당 클래스에서 마우스 우클릭 > Source > Generate Getters and Setters
    -> 해당 변수를 선택하여 getter와 setter를 만들 수 있음!
    -> setter를 생성할 수 있는데 세부적인 로직은 직접 제작해야함!
  • 내부 클래스
package ch06.sec14;

public class Car {
	// private 필드로 해당 클래스에서만 사용 가능
	private int speed;
	private boolean stop;
	
	
	// get : set에서 설정한 값을 리턴함
	public int getSpeed() {
		return speed;
	}
	// getSpeed() : setSpeed()에서 설정한 speed 값을 리턴하는 역할
	
	public void setSpeed(int speed) {
		if(speed>0 && speed<=250) {
			this.speed = speed;
		}
		//speed 필드가 0보다 크거나 250보다 작거나 같을 때 speed를 출력
		//set 메소드 : private 형태의 필드를 설정하는데 쓰임
	}
	
	// boolean 타입의 private 필드는 get 대신 is를 사용
	public boolean isStop() {
		return stop;
	}
	// isStop() : setStop()에서 설정한 stop 값을 리턴함
	// 멈추는 구문!
	
	public void setStop(boolean stop) {
		// boolean 타입 stop 매개변수에 참과 거짓 중에 하나를 받음
		this.stop = stop;
		// 매개변수에서 받은 값을 위의 private 필드에 대입함
		if(stop == true) {
			this.speed = 0;
		}
		// true를 받으면 속도 0으로 설정
	}
	
}
  • 외부 클래스
package ch06.sec14;

public class CarExam {
	public static void main(String[] args) {
		Car c = new Car();
		// Car 객체 생성
		
		c.setSpeed(-50);
		// speed = -50, 잘못된 값이므로 속도가 0(초기값)이 나옴
		System.out.println("현재 속도= " + c.getSpeed());
		
		c.setSpeed(60);
		// speed = 60
		System.out.println("현재 속도= " + c.getSpeed());
		
		if(!c.isStop()) {
			// 멈춤
			// !c.isStop 쓰는 이유!
			// boolean 타입 필드의 초기값은 false이기 때문에 false를 그대로 받으면 실행이 안됨
			// 그래서 ! 연산자를 사용하여 값을 반대로 바꿔줘야함.
			
			c.setStop(true);
			// true를 받고 c.setStop()에도 true 값을 넣어줌
			// setStop에서 true를 받았기 때문에 해당 함수에서 설정한 대로
			// speed 값은 0이됨
		}
		System.out.println("현재 속도= " + c.getSpeed()); // 0
	}
}

싱글톤 패턴

  • 단 한 개의 객체만을 생성해서 사용하기 위해 만들어진 패턴

  • 생성자를 private 접근 제한해서 외부에서 new 연산자로 생성자를 호출할 수 없도록 막아서 외부에서 마음대로 객체를 생성하지 못하게 함

  • private 정적 필드 선언을 통해 객체를 만들고 해당 생성자를 private화 시킴

  • 대신 정적 메소드를 사용해 간접적으로 객체를 얻을 수 있음!

  • 싱글톤 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있음

  • 이를 잘 활용한 것이 Calendar 객체임!

  • 형태

	//private 접근 권한을 가지는 정적 필드 선언과 초기화
	private static 클래스명 정적필드명 = new 클래스명();
    
    //private 접근 권한을 가지는 생성자 선언
    private 클래스명(){
    }
    
    //private로 접근하였기 때문에 new를 이용하여 객체를 생성할 수 없음
    
    //public 접근 권한을 갖는 정적 메소드 선언
    public static 클래스 메소드명(){
    	return 정적필드명; // 메소드를 선언하여 정적필드값을 리턴
    }
    
    // 대신 public으로 접근한 메소드를 통해 해당 객체를 생성할 수 있음
    
  • 내부 클래스
package ch06.sec15;

public class Singleton {
	
	// private 접근 권한을 가지는 정적 필드를 선언하고 초기화 해줌
	private static Singleton single = new Singleton();
	
	private Singleton() {
		// private 접근 권한을 가지는 기본생성자 메소드를 만듦
		// 이로서 외부 클래스에서 new 연산자를 통해 해당 객체를 생성할 수 없게됨
	}
	
	public static Singleton get() {
		// public 접근 권한을 가지는 메소드를 선언하여 Singleton 이라는 객체를 선언하고자함
		// static 형태의 정적 메소드를 선언하는 이유는 new 연산자로 선언하여 만들 수 없고
		// 메소드를 하나만 사용하고자 하기 때문
		
		return single;
		// singleton 객체의 정적필드인 single의 값을 그대로 리턴함
	}
}
  • 외부 클래스
package ch06.sec15;

public class SingletonExam {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		// 내부 클래스에서 private로 접근하였고, 정적필드로 선언했기 때문에
		// new 연산자로 인해 호출할 수 없음
//		Singleton obj1 = new Singleton();
//		Singleton obj2 = new Singleton();
		
		// 따라서 public 접근 권한을 가지는 정적 메소드를 이용해 객체로 접근해야함
		Singleton obj3 = Singleton.get();
		Singleton obj4 = Singleton.get();
		
		if(obj3 == obj4) {
			System.out.println("같은 싱글톤 객체");
			// 같은 객체를 참조하므로 true
		}
		else {
			System.out.println("다른 싱글톤 객체");
		}
	}

}
profile
끄작끄작

0개의 댓글