패키지의 선언 방법
package 패키지명;
class 클래스명 {}
package 패키지명;
으로 선언하지 않으면 해당 클래스 파일은 이름없는 패키지(default package)에 속하게 됩니다.
bin 폴더와 src 폴더는 왜 있나요?
bin 폴더: 컴파일된 클래스 파일(.class)가 있는 곳
src 폴더: 소스 파일(.java)가 있는 곳
터미널에서 해당 패키지의 클래스를 실행시키고 싶다면?
1. 해당 패키지가 속해있는 폴더의 bin 폴더로 경로를 바꾼다.cd project/bin
2.java 패키지이름.클래스이름
을 실행한다.
매번 실행할 때 위의 과정을 생략하고 싶다면 클래스 패스(class path)를 지정해주는 방법이 있습니다.
클래스 패스
- 클래스 파일의 위치를 알려주는 경로
- os 별로 classpath(환경변수)를 지정하는 방법이 있으며 이를 통해 패키지의 루트를 등록해주어야 한다.
작성 방법
import 패키지명.클래스명;
import 패키지명.*;
* 은 모든 클래스
Intellij -> alt+enter를 하면 해당 클래스의 import 문을 자동으로 작성
package main; // 패키지 선언
import util.java; // import 문
import java.util.*; // import 문
public class Main { // 클래스 정의
public static main(String[] args){
}
}
클래스명을 쓰는 것과 모든 클래스를 사용할 수 있는 * 의 성능 차이
- import 문은 컴파일 시에 처리되므로 프로그램의 성능에 영향이 없습니다.
- 하지만 사용할 클래스를 작성하는 것이 무엇을 썻는지 알 수 있어서 가독성에 좋습니다.
java.lang 패키지의 클래스
- String, Object, System, Thread ... 등등
import java.lang.*; // 생략가능 (원래는 써주어야 한다.)
static import
- static 멤버를 사용할 때 클래스 이름을 생략할 수 있게 해준다.
import static java.lang.Math.*; // Math 클래스의 모든 static 멤버 사용
import static java.lang.System.out;
class Main {
public static main(String[] args){
out.println(random());
}
}
Math.random()
→ random()
System.out.println()
→ out.println()
import static java.lang.System.out;
public class Main {
public static void main(String[] args){
Parent p = new Parent();
p.printMembers(); // ok
out.println(p.prv); // 에러 (private 이기 때문)
out.println(p.dft);
out.println(p.prt);
out.println(p.pub);
}
}
class Parent {
private int prv; // 같은 클래스
int dft; // 같은 패키지
protected int prt; // 같은 패키지 + 자손(다른 패키지)
public int pub; // 접근제한 없음.
public void printMembers() {
out.println("prv = " + prv);
out.println("dft = " + dft);
out.println("prt = " + prt);
out.println("pub = " + pub);
}
}
package util;
import main.Parent;
import static java.lang.System.out;
class Child extends Parent {
public void printMembers(){
out.println("prv = " + prv); // 에러 -> 같은 클래스가 아니기 때문에
out.println("dft = " + dft); // 에러 -> 같은 패키지가 아니기 때문에
out.println("prt = " + prt); // protected -> 자손 클래스이기 때문에 접근 가능
out.println("pub = " + pub); // public -> 접근제한이 없기 때문에 접근 가능
}
}
abstract class AbstractClass { // 추상 클래스(추상 메서드를 포함한 클래스)
abstract void method(); // 추상 메서드(구현부가 없는 메서드)
}
추상 메서드는 메서드의 구현부가 완성되지 않았다고 판단할 때 붙여줍니다.
이러한 추상 메서드가 하나라도 있으면 무조건 추상 클래스입니다.
abstract
가 붙은 클래스는 인스턴스 생성이 불가합니다.
추상 클래스는 언제 객체를 만들 수 있나요?
추상 클래스를 상속받아서 완전한 클래스를 만든 후에 상속받은 클래스를 통해 객체를 생성할 수 있습니다.
package main;
public class Main {
public static void main(String[] args){
// AbstractClass abClass = new AbstractClass(); --> abstract class 이기 때문에 에러
// 아직 완성되지 않은 클래스의 메서드를 오버라이딩 하여 완성시키고 인스턴스를 생성한다.
AbstractClass abClass = new AbstractClass() {
@Override
void abstractMethod() {
System.out.println("오버라이딩한 abstract method!");
}
};
// 완성된지 않은 클래스를 상속받아 완성시킨 클래스를 사용하여 인스턴스 생성
ChildClass childClass = new ChildClass();
abClass.abstractMethod();
childClass.abstractMethod();
}
}
abstract class AbstractClass {
abstract void abstractMethod();
}
class ChildClass extends AbstractClass{
void abstractMethod(){
System.out.println("상속받은 abstract method!");
}
}
// 출력
>> 오버라이딩한 abstract method!
>> 상속받은 abstract method!