서로 관련된 클래스의 묶음
클래스는 클래스 파일(*.class), 패키지는 폴더. 하위 패키지는 하위 폴더
클래스는 실제 이름(full name)은 패키지를 포함.(java.lang.String)
rt.jar는 클래스들을 압축한 파일(JDK설치경로₩jre₩lib에 위치)
(java9부터는 rt.jar 개념 사라짐 => module개념으로 바뀜)
패키지는 소스파일의 첫 번재 문장으로 단 한번 선언
같은 소스 파일의 클래스들은 모두 같은 패키지에 속하게 된다.
패키지 선언이 없으면 이름없는(unnamed)패키지(default package)에 속하게 된다.
클래스 파일(*.class)의 위치를 알려주는 경로(path)
환경변수 classpath로 관리하며, 경로간의 구분자는 ';'를 사용
classpath(환경변수)에 패키지의 루트를 등록해줘야 함.
클래스를 사용할 때 패키지 이름을 생략할 수 있다.
컴파일러에게 클래스가 속한 패키지를 알려준다.
import문은 패키지문과 클래스선언의 사이에 선언한다. (1.패키지선언 2.import문 3.클래스정의 순서로)
단축키: ctrl+shift+o 자동으로 import문 만들어줌
import 패키지명.클래스명;
또는
import 패키지명.*; // * -> 모든 클래스를 의미
java.lang패키지의 클래스는 Import하지 않고도 사용할 수 있다.
String, Object, System, Thread...
import java.lang.*; // 생략 가능
import문은 컴파일 시에 처리되므로 프로그램의 성능에 영향 없음.
import java.util.Calendar; import java.util.Date; import java.util.ArrayList; 를 import java.util.*; 로 한 번에 쓸 수 있다.
이름이 같은 클래스가 속한 두 패키지를 import할 때는 클래스 앞에 패키지명을 붙여줘야 한다.
import java.sql.*; // java.sql.Date import.java.util.*; // java.util.Date // Date 이름이 동일한 클래스를 import할 때 패키지명 명시
static멤버를 사용할 때 클래스 이름을 생략할 수 있게 해준다.
(그러나 클래스명을 다 생략하면 알아보기 어려우니까,,, 꼭 필요할 때만 쓰기)import static java.lang.Integer.*; // Integer클래스의 모든 static 메서드 import static java.lang.Math.random; // Math.random()만. 괄호 안 붙임 import static java.lang.System.out; // System.out을 out만으로 참조가능 System.out.println(Math.random()); ---> out.println(rander());
클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미 부여
접근 제어자 public, protected, (default), private
그 외 static, final, abstract, native, transient, synchronized, volatile, strictfp
하나의 대상에 여러 제어자를 같이 사용 가능(접근 제어자는 하나만)
public class Ex {
public static final int WIDTH = 200; // 접근 제어자를 제일 앞에
public static void main(String[] args) {
System.out.println("WIDTH="+WIDTH);
}
}
class Ex { // 객체 생성 없이 사용 가능
static int width = 200; // 클래스 변수(static 변수), 간단 초기화(명시적)
static int height = 120; // 클래스 변수(static 변수), 간단 초기화(명시적)
static { // 클래스 초기화 블럭
// static 변수의 복잡한 초기화 수행
}
static int max(int a, int b) { // 클래스 메서드(static 메서드)
return a > b ? a : b; // 인스턴스 메서드, 인스턴스 변수 사용 불가
}
final class Ex { // 조상이 될 수 없는 클래스
final int MAX_SIZE = 10; // 값을 변경할 수 없는 멤버변수(상수)
final void getMaxSize() { // 오버라이딩할 수 없는 메서드(변경불가)
final int LV = MAX_SIZE; // 값을 변경할 수 없는 지역변수(상수)
return MAX_SIZE;
}
}
abstract calss Ex { // 추상 클래스(추상 메서드를 포함한 클래스, 미완성 클래스)
abstract void move(); // 추상 메서드(선언부는 있으나 구현부{}가 없는 메서드, 미완성 메서드)
}
Ex a = new Ex(); // 에러! 추상 클래스의 인스턴스 생성 불가(미완성 클래스이므로 객체 생성 불가)
// 언제 만들 수 있나? 추상클래스를 상속받아서 완전한 클래스를 만들어야 객체 생성 가능하다.
private 같은 클래스 내에서만 접근이 가능하다.
(default) 같은 패키지 내에서만 접근이 가능하다.
protected 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.
public 접근 제한이 전혀 없다.
public > protected > (default) > private
접근 제어자 중에 class 앞에 붙일 수 있는 건 public, (default) 두 가지만 가능
멤버에는 public, protected, (default), private 네 가지 다 붙일 수 있다.
접근 제어자를 사용하는 이유?
외부로부터 데이터를 보호하기 위해서 (직접 접근을 막고 메서드를 통한 간접 접근을 허용 하는 것)
외부에는 불필요한, 내부적으로만 사용되는 부분을 감추기 위해서
public class Time { // 접근 제어자를 private으로 하여 외부에서 직접 접근하지 못하도록 한다.
private int hour;
private int minute;
private int seconde;
public void setHour(int hout) { // 메서드는 public (메서드를 통한 간접 접근 허용)
if (hour < 0 || hour > 23) return;
this.hour = hour;
}
public int getHour() { return hour; }
}