[Java] 자바의 정석 7장 (3) - 패키지, import, 제어자

토닉·2021년 9월 17일
0

Java

목록 보기
12/13
post-thumbnail

📌 패키지

  • 서로 관련된 클래스의 묶음
  • 클래스는 클래스 파일, 패키지는 폴더
  • 클래스의 실제 이름은 패키지를 포함
  • 패키지는 다른 패키지를 포함할 수 있다.

패키지의 선언 방법

package 패키지명;

class 클래스명 {}

package 패키지명;으로 선언하지 않으면 해당 클래스 파일은 이름없는 패키지(default package)에 속하게 됩니다.

bin 폴더와 src 폴더는 왜 있나요?
bin 폴더: 컴파일된 클래스 파일(.class)가 있는 곳
src 폴더: 소스 파일(
.java)가 있는 곳

터미널에서 해당 패키지의 클래스를 실행시키고 싶다면?
1. 해당 패키지가 속해있는 폴더의 bin 폴더로 경로를 바꾼다.cd project/bin
2. java 패키지이름.클래스이름을 실행한다.

매번 실행할 때 위의 과정을 생략하고 싶다면 클래스 패스(class path)를 지정해주는 방법이 있습니다.

클래스 패스

  • 클래스 파일의 위치를 알려주는 경로
  • os 별로 classpath(환경변수)를 지정하는 방법이 있으며 이를 통해 패키지의 루트를 등록해주어야 한다.

📌 import 문

  • 클래스를 사용할 때 패키지이름을 생략할 수 있다.
  • 컴파일러에게 클래스가 속한 패키지를 알려준다.
  • java.lang 패키지의 클래스는 import 하지 않고도 사용할 수 있다.

작성 방법

  • 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()

📌 제어자

  • 형용사
  • 클래스와 클래스의 멤버에 부가적인 의미 부여

📍 접근 제어자

  • public : 접근 제한이 전혀 없다.(어디서든 사용 가능)
  • protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손 캘래스에서 접근 가능
  • (default) : 같은 패키지 내에서만 접근이 가능
  • private : 같은 클래스 내에서만 접근이 가능
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 -> 접근제한이 없기 때문에 접근 가능
    }
}

📍이 외 제어자들

  • static, final, abstract, (native, transient, 등)

static - 전역의

  • 모든 인스턴스에 공통적으로 사용되는 클래스 변수에 작성
  • 인스턴스를 생성하지 않아도 사용 가능
  • static 메서드는 인스턴스멤버를 직접 사용할 수 없다.

final - 마지막의, 변경할 수 없는

  • 대상: 클래스, 메서드, 멤버변수, 지역변수
  • final 클래스: 조상이 될 수 없는 클래스
  • final 메서드: 오버라이딩을 통해 재정의가 불가능한 메서드
  • final 변수: 변경할 수 없는 상수

abstract - 추상의, 미완성의

  • 아직 완성되지 않은 메서드, 클래스
  • 대상: 클래스, 메서드
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!
profile
우아한테크코스 4기 교육생

0개의 댓글