JAVA SPRING/java

JAVA_009) 클래스외부(패키지,임포트), 자바제어자(public,protected,default,private), Static

오동순이 2023. 4. 26. 23:14

클래스외부 구성요소

패키지와 임포트

패키지를 사용하는 이유?

  - 유사한 기능을 수행하는 클래스 파일들을 묶어서 관리

  - 클래스간의 이름 충돌 방지

 

 

 

pack01

package pack01;

public class A {
	public int m =3;
    public int n = 5;
}

 

pack02- error

package pack02;

public class B {
	void bcd() {
    	A a = new A(); // error
        System.out.println(a.m);
        System.out.println(a.n);
    }
}

 

 

pack02에서 임포트 하지 않고 사용하려면 패키지명을 다 가져와야함

package pack02;

public class B {
	void bcd() {
    	pack01.A a = new pack01.A(); // 임포트하지 않고 패키지명으로 객체 생성
        System.out.println(a.m);
        System.out.println(a.n);
    }
}

 

혹은 임포트 해서 써야함

package pack02;
import pack01.A; // 임포트했기때문에

public class B {
	void bcd() {
    	A a = new A(); // 객체생성가능
        System.out.println(a.m);
        System.out.println(a.n);
    }
}

 

 

자바제어자

 

접근지정자 - 4가지 접근지정자의 사용 가능 범위

접근 범위 넓음 접근 지정자 사용 가능 범위
public 동일 패키지의 모든 클래스 + 다른 패키지의  모든 클래스에서 사용 가능
  protected 동일 패키지의 모든 클래스 + 다른 패키지의 자식 클래스에서 사용 가능
default 동일 패키지의 모든 클래스에서 사용 가능
접근 범위 좁음 private 동일 클래스에서 사용 가능

 

 

* 멤버 및 생성자에 적용되는 4가지 접근 지정자

Java_Ex06폴더- pack01(패키지), pack02(패키지), AccessModifierOfMember(main메서드)

Java_Ex06 - pack01 - A class

package pack01;

public class A {
    public int a = 1;
    protected int b = 2;
    int c = 3;
    private int d = 4;

    public void print() {
        System.out.print(a + " ");
        System.out.print(b + " ");
        System.out.print(c + " ");
        System.out.print(d);
        System.out.println();
    }
}

 

Java_Ex06 - pack01 - B class

package pack01;

public class B {
    public void print() {
        // 객체 생성
        A a = new A(); // 다른 클래스의 
                       // 인스턴스 멤버를 사용하기 위해 객체 생성
        
        // 멤버 활용
        System.out.print(a.a + " "); // public 사용가능
        System.out.print(a.b + " "); // protected 사용가능
        System.out.print(a.c + " "); // default 사용가능

        // System.out.print(a.d + " ");
        // private 접근 지정자로 지정된 필드는 접근 불가능
        System.out.println();

    }
    
}

 

Java_Ex06 - pack02 - C class

package pack02;

import pack01.A; 
// A는 임포트 되어있지만 extends 상속 받지는 않은 상태일때

public class C {
    public void print() {
        // 객체 생성
        A a = new A();

        // 멤버 활용
        System.out.print(a.a + " "); // public 사용가능

        // System.out.print(a.b + " ");
        // System.out.print(a.c + " ");
        // System.out.print(a.d + " ");
        // 다른 패키지 내의 클래스에서는 자식 클래스가 아닐때는 public만 사용가능

        System.out.println();
    }
}

 

Java_Ex06 - pack02 - D class

package pack02;

import pack01.A;

// A는 import 되어 있고 extends(상속) 되어있음
// D class는 A의 자식 class이다.
public class D extends A{
    public void print() {
        // 멤버 활용
        System.out.print(a + " "); // public 사용가능
        System.out.print(b + " "); // protected 사용가능
        
        // 자식 클래스는 다른 패키지에 있어도
        // 객체의 생성 없이 protected 접근지정자 필드까지 접근가능

        // System.out.print(c + " ");
        // System.out.print(d + " ");

        System.out.println();
    }

}

 

Java_Ex06 - main메서드 AccessModifierOfMember

import pack01.A;
import pack01.B;
import pack02.C;
import pack02.D;

public class AccessModifierOfMember {
    public static void main(String[] args) {
        
        A a = new A();
        B b = new B();
        C c = new C();
        D d = new D();

        a.print();
        b.print();
        c.print();
        d.print();

    } 
}

출력 결과

1 2 3 4   // 모든접근
1 2 3      // private접근불가
1            // public만 접근가능 - 다른패키지
1 2         // public , protected(extends 상속 하여 자손클래스로 됨) 접근 가능

 

 

 

static 제어자

static은 클래스의 멤버(필드, 메섣, 이너클래스)에 사용하는 제어자

객체를 생성하고 사용할 수 있는 멤버 : 인스턴스 멤버(static이 붙어있지 않은 것)

static이 붙어 있는 멤버 , 객체를 생성하지 않고 바로 사용 가능 : 정적 멤버

 

인스턴스 필드와 정적필드의 활용방법

class A {
    int m = 3; // 인스턴스 필드
    static int n = 5; // 정적 필드(static 필드)
}

public class StaticField_1 {
    public static void main(String[] args) {
        // 인스턴스 필드 활용 방법(객체를 생성한 후 사용 가능)
        A a1 = new A();
        System.out.println(a1.m);

        // 정적 필드 활용방법
        // 1. 객체 생성 없이 클래스 명으로 바로 활용
        System.out.println(A.n);
        // 2. 객체를 생성한 후 활용(권장하지 않음)
        A a2 = new A();
        System.out.println(a2.n);
    }
}

 

정적 필드의 공유 특성 예

class AA {
    int m = 3; // 인스턴스 필드
    static int n = 5; // 정적 필드
}

public class StaticField_2 {
    public static void main(String[] args) {
        AA a1 = new AA();
        AA a2 = new AA();

        // 인스턴스 필드
        a1.m = 5;
        a2.m = 6;
        System.out.println(a1.m); // 5
        System.out.println(a2.m); // 6

        // 정적 필드 - 객체간 공유
        a1.n = 7;
        a2.n = 8;
        System.out.println(a1.n); // 8
        System.out.println(a2.n); // 8

        AA.n = 9 ;
        System.out.println(a1.n); // 9
        System.out.println(a2.n); // 9
    }
}

 

인스턴스 메서드와 정적 메서드

class AAA {
    void abc() { // 인스턴스 메서드
        System.out.println("instance method");
    }
    static void def() { // 정적 메서드
        System.out.println("static method");
    }
}

public class StaticMethod {
    public static void main(String[] args) {
        // 인스턴스 메서드 활용 (객체를 생성한 후 사용 가능)
        AAA a1 = new AAA();
        a1.abc();

        // 정적 메서드 활용
        // 1. 클래스 명으로 바로 접근해 사용
        AAA.def();
        // 2. 객체를 생성한 후 사용(권장X)
        AAA a2 = new AAA();
        a2.def();

    }
}