관리 메뉴

나구리의 개발공부기록

자바의 정석 기초편 ch7 - 17 ~ 21 [제어자, static, final, abstract, 접근제어자] 본문

유튜브 공부/JAVA의 정석 기초편(유튜브)

자바의 정석 기초편 ch7 - 17 ~ 21 [제어자, static, final, abstract, 접근제어자]

소소한나구리 2023. 11. 24. 11:40

1) 제어자 - modifier

  • 클래스와 클래스의 멤버(멤버 변수, 메서드)에 부가적인 의미 부여함
  • 접근 제어자는 하나의 대상에 하나만 사용 가능함
  • 그 외 제어자는 여러 제어자를 같이 사용할 수 있음
  • 순서는 상관없으나 대부분 접근 제어자를 가장 앞에 사용

(1) 접근 제어자

  • public, protected, (default), private - 4개 중에 한개만 붙힐 수 있음
  • 디폴트는 아무것도 안붙히는 것

(2) 그 외 제어자

  • static, final, abstract, native, transient, synchronized, volatile, strictfp 등등
public class ex07_write {

	// 접근 제어자를 가장 앞에 쓰는 것이 관례
	// 접근 제어자는 한개밖에 사용 불가함
	public static final int WIDTH = 200;	// 접근제어자 1개 그 외 제어자 2개 사용
	
	public static void main(String[] args) {	// 접근제어자 1개 그 외 제어자 1개 사용
		System.out.println("width="+WIDTH);
	}
}

2) static - 클래스의, 공통적인

제어자 대상 의미
static 멤버변수 모든 인스턴스에 공통적으로 사용되는 클래스 변수
클래스 변수는 인스턴스를 생성하지 않고도 사용 가능
클래스가 메모리에 로드 될 때 생성
메서드 인스턴스를 생성하지 않고도 호출이 가능한 메서드
static 메서드 내에서는 인스턴스 멤버들을 직접 사용 불가

 

(1) 예제

class StaticTest {

	// cv 간단 초기화
	static int width = 200;		// cv
	static int height = 200;	// cv

	static {	// 클래스 초기화 블럭(static 블럭) = cv 복잡 초기화
	//  초기화 할 문장
	}
	
	static int max(int a, int b) {	// static 메서드(클래스 메서드)
		// iv, im는 직접 사용할 수 없음
		return a > b ? a : b;
	}
}

// cv, static 메서드 둘다 객체 없이 사용 가능

3) final - 마지막의, 변경 될 수 없는

  • 대표적인 final 클래스
  • String 클래스: 패스워드 등을 자손클래스에서 재정의 할 수 있기 때문에 막아 둠(보안 문제)
  • Math 클래스 : static메서드의 집합이므로 굳이 상속받아서 쓸일이 없음
제어자 대상 의미
final 클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스
final로 지정된 클래스는 다른 클래스의 조상이 될 수 없음
즉, 제일 마지막 자손 클래스가 됨
메서드 변경 될 수 없는 메서드
final로 지정된 메서드는 오버라이딩을 할 수 없음(재정의 불가)
멤버변수 값을 변경할 수 없는 상수가 됨
지역변수

(1) 예제

final class FinalTest {	// 조상이 될 수 없는 클래스(상속 계층도의 가장 마지막 클래스)
	final int MAX_SIZE = 10;	// 값을 변경할 수 없는 멤버변수(상수)
	
	final void getMaxSize() {	// 오버라이딩을 할 수 없는 메서드(변경불가)
		final int LV = MAX_SIZE;	// 값을 변경할 수 없는 지역변수(상수)
	}	
}

4) abstract - 추상의, 미완성의

  • 추상 메서드(미완성 메서드)를 가지고 있으면 무조건 추상클래스(미완성 클래스)
  • 추상 클래스(미완성 클래스)는 미완성 설계도이므로 객체를 생성할 수 없음
  • abstract class는 그 자체만으로 객체 생성이 불가능 하기때문에 상속을 통해 완전한 클래스를 만들고(추상 메서드를 구현) 객체 생성 가능 -> 추후 더 배울 예정
제어자 대상 의미
abstract 클래스 클래스 내에 추상 메서드가 선언되어 있음을 의미
메서드 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알림

(1) 예제

// 추상메서드를 가지고 있으면 무조건 추상 클래스(미완성 클래스)
abstract class AbstractTest {	// 추상 클래스(추상메서드를 포함한 클래스)

    // 미완성 메서드
	abstract void move();	// 추상 메서드(구현부가 없는 메서드,{}이 없음)
}

// 상속을통해서 완전한 클래스를 만든 후에 객체 생성 가능
AbstractTest a = new AbstractTest(); // 에러! 추상클래스의 객체 생성불가

 5) 접근제어자

접근제어자 대상 의미
private 멤버 같은 클래스 내에서만 접근이 가능
(default) 클래스
멤버
같은 패키지 내에서만 접근이 가능
protected 멤버 같은 패키지 내에서도 접근이 가능하고 다른 패키지의 자손클래스는 접근이 가능
public 클래스
멤버
접근 제한이 전혀 없음
제어자 같은클래스 같은패키지 다른패키지의 자손클래스 전체
public O O O O
protected O O O  
(default) O O    
private O      

(1) 예제1

  • public은 모두 에러가 안나고 private 변수를 다른 클래스에서 사용하려고하면 에러가남
package pkg1;

public class MyParent {	// 접근제어자가 Public - 다른패키지에서도 사용 가능
	private		int prv;	// 같은 클래스
			int dft;	// 같은 패키지 (default)
	protected	int prt;	// 같은 패키지 + 다른 패키지의 자손 클래스
	public		int pub;	// 접근제한없음
	
	public void printMembers() {
		System.out.println(prv);	// OK
		System.out.println(dft);	// OK
		System.out.println(prt);	// OK
		System.out.println(pub);	// OK
	}
}

class MyParenTest {	// 접근제어자가 default - 같은패키지에서만 사용 가능
	public static void main(String[] args) {
		MyParent p = new MyParent();
		System.out.println(p.prv);	// 에러 = private class, 같은 클래스가 아님(범위 벗어남)
		System.out.println(p.dft);	// OK
		System.out.println(p.prt);	// OK
		System.out.println(p.pub);	// OK
	}
}

 

(1) 예제2

  • private, default 변수를 다른 패키지의 클래스에서 사용하려고하면 에러가 발생함
  • protected변수를 선언한 클래스를 다른 패키지에서 사용할 때 상속받으면 사용이 가능하고 상속받지 않으면 사용 불가능함
package pkg2;

// 패키지를 불러올 수 있게 임포트문 작성, 없으면 MyParent클래스를 찾을 수 없다는 에러 발생
import pkg1.MyParent;

class MyChild extends MyParent {
	public void printMembers() {
		System.out.println(prv);	// 에러 - private class 같은 클래스에서만 사용가능	
		System.out.println(dft);	// 에러 - default class 같은 패키지에서만 사용가능
		System.out.println(prt);	// OK
		System.out.println(pub);	// OK
	}
}

public class MyParentTest2 {
	public static void main(String[] args) {
		MyParent p = new MyParent();
		
		// 에러 = private class, 같은 클래스가 아님(범위 벗어남)
		System.out.println(p.prv);
        
		// 에러 - default class 같은 패키지에서만 사용가능
		System.out.println(p.dft);	
        
		// 에러 - protected class 다른 패키지+다른 패키지의 자손클래스 에서 사용가능
		System.out.println(p.prt);	
        
		System.out.println(p.pub);	// OK - 제한없음
	}
}

 

 

** 출처 : 남궁성의 정석코딩_자바의정석