군만두의 IT 공부 일지

[스터디4] 02. 클래스 본문

프로그래밍/Java

[스터디4] 02. 클래스

mandus 2025. 1. 31. 23:13

목차

     

    이번에는 6장에서 클래스의 주요 부분에 대해서 정리해보려고 합니다.

    6장. 참조 타입

    6.9 인스턴스 멤버

    • 필드와 메소드는 선언 방법에 따라 인스턴스 멤버정적 멤버로 분류할 수 있음.
    구분 설명
    인스턴스(instance) 멤버 객체에 소속된 멤버
    (객체를 생성해야만 사용할 수 있는 멤버)
    정적(static) 멤버 클래스에 고정된 멤버
    (객체 없이도 사용할 수 있는 멤버)
    • 인스턴스 멤버 선언 및 사용
      • 아래처럼 Car 클래스에 gas 필드와 setSpeed() 메소드를 선언하면 인스턴스 멤버가 됨.
    public class Car {
        // 인스턴스 필드 선언
        int gas;
        
        // 인스턴스 메소드 선언
        void setSpeed(int speed) { ... }
    }
    • this 키워드
      • 객체 내부에서는 인스턴스 멤버에 접근하기 위해 this를 사용할 수 있음.
      • 생성자와 매개변수명이 인스턴스 멤버인 필드명과 동일한 경우, 인스턴스 필드임을 강조하고자 할 때 this를 주로 사용함.
    public class Car {
        // 필드 선언
        String model;
        int speed;
        
        // 생성자 선언
        Car(String model) {
        	this.model = model;		// this 생략 불가
        }
        
        // 메소드 선언
        void setSpeed(int speed) {
        	this.speed = speed;		// this 생략 불가
        }
        
        void run() {
        	this.setSpeed(100);	// this 생략 가능
            System.out.println(this.model + "가 달립니다.(시속:" + this.speed + "km/h)");	// this 생략 가능
        }
    }

    6.10 정적 멤버

    • 자바는 클래스 로더(loader)를 이용해서 클래스를 메소드 영역에 저장하고 사용함.
    • 정적(static) 멤버: 메소드 영역의 클래스에 고정적으로 위치하는 멤버. 객체를 생성할 필요 없이 클래스를 통해 사용이 가능함.
    • 정적 멤버 선언
      • 필드와 메소드를 정적 멤버로 선언하려면 static 키워드를 추가함.
      • 객체마다 가지고 있을 필요성이 없는 공용적인 필드는 정적 필드로 선언함.
    public class Calculator {
        // 정적 필드 선언
        String color;
        
        // 정적 메소드
        static int plus(int x, int y) { return x + y; }
        static int minus(int x, int y) { return x - y; }
    }
    • 정적 멤버 사용
      • 클래스가 메모리로 로딩되면 정적 멤버를 바로 사용할 수 있음. 클래스 이름과 함께 도트(.) 연산자로 접근함.
    int result1 = Calculator.plus(10, 5);
    int result2 = Calculator.minus(10, 5);
    • 정적 블록
      • 정적 필드는 필드 선언과 동시에 초기값을 주는 것이 일반적임.
      • 복잡한 초기화 작업이 필요하다면 정적 블록(static block)을 이용해야 함.
      • 정적 블록은 클래스가 메모리로 로딩될 때 자동으로 실행됨. 정치 블록이 클래스 내부에 여러 개가 선언되어 있으면 선언된 순서대로 실행됨.
    public class Television {
        static String company = "MyCompany";
        static String model = "LCD";
        static String info = createInfo();
    
        static String createInfo() {	// 정적 블록
            return company + " - " + model;
        }
    }
    • 인스턴스 멤버 사용 불가
      • 정적 메소드와 정적 블록은 객체가 없어도 실행되기 때문에 내부에 인스턴스 필드인스턴스 메소드를 사용할 수 없음. this도 사용할 수 없음.
      • 정적 메소드정적 블록에서 인스턴스 멤버를 사용하고 싶으면 객체를 먼저 생성하고 참조 변수로 접근해야 함. main() 메소드도 동일함.
    static void method3() {
        // 객체 생성
        ClassName obj = new ClassName();
        
        // 인스턴스 멤버 사용
        obj.field1 = 10;
        obj.method1();
    }

    6.11 final 필드와 상수

    • 인스턴스 필드정적 필드는 언제든지 값을 변경할 수 있음.
    • 값을 변경하는 것을 막고 읽기만 허용해야 할 때 final 필드와 상수를 선언해서 사용함.
    • final 필드 선언
      • final 필드는 초기값이 저장되면 이것이 최종적인 값이 되어서 프로그램 실행 도중에 수정할 수 없음.
      • 고정된 값이라면 필드 선언 시에 주는 것이 가장 간단함.
      • 복잡한 초기화 코드가 필요하거나 객체 생성 시에 외부에서 전달된 값으로 초기화한다면 생성자에서 해야 함.
    final 필드에 초기값을 줄 수 있는 방법
    1. 필드 선언 시에 초기값 대입
    2. 생성자에서 초기값 대입
    static void method3() {
        // 객체 생성
        ClassName obj = new ClassName();
        
        // 인스턴스 멤버 사용
        obj.field1 = 10;
        obj.method1();
    }
    • 상수 선언
      • 상수(constant):
        • 불변의 값을 저장하는 필드
        • 객체마다 저장할 필요가 없고, 여러 개의 값을 가지면 안 되기 때문에 static이면서 final임.
    // 상수 선언 1
    static final 타입 상수;
    
    // 상수 선언 2
    static final 타입 상수;
    static {
    	상수 = 초기값;
    }

    6.12 패키지

    • 패키지(package):
      • 클래스의 일부분으로, 클래스를 식별하는 용도로 사용함.
      • 개발 회사 도메인 이름의 역순으로 만듦.
    • 패키지 선언
      • 패키지 선언: package 키워드와 함께 패키지 이름을 기술한 것. 소스 파일 최상단에 위치함.
        • 패키지 디렉토리는 클래스를 컴파일하는 과정에서 자동으로 생성됨.
        • 컴파일러는 클래스의 패키지 선언을 보고 디렉토리를 자동 생성시킴.
      • 패키지 이름
        • 소문자로 작성하는 것이 관례임.
        • 이름이 중복되지 않도록 회사 도메인 이름의 역순으로 작성함.
        • 마지막에는 프로젝트 이름을 붙임.
    • import 문
      • 같은 패키지에 있는 클래스는 아무런 조건 없이 사용할 수 있지만, 다른 패키지에 있는 클래스를 사용하려면 import 문을 이용해서 어떤 패키지의 클래스를 사용하는지 명시해야 함.
      • import 문이 작성되는 위치는 패키지 선언과 클래스 선언 사이임.
      • import 키워드 뒤에는 사용하려는 클래스의 이름을 기술함. 동일한 패키지에 포함된 클래스들을 사용하려면 클래스 이름을 생략하고 *을 사용할 수 있음.
      • import 문은 하위 패키지는 포함하지 않음.

    6.13 접근 제한자

    • 객체의 필드를 외부에서 변경하거나 메소드를 호출할 수 없도록 막아야 할 필요가 있음.
    • 중요한 필드와 메소드가 외부로 노출되지 않도록 객체의 무결성을 유지하기 위해서 접근 제한자(Acces Modifier)를 사용함.
    접근 제한자 제한 대상 제한 범위
    public 클래스, 필드, 생성자, 메소드 없음
    protected 필드, 생성자, 메소드 같은 패키지이거나, 자식 객체만 사용 가능
    (default) 클래스, 필드, 생성자, 메소드 같은 패키지
    private 필드, 생성자, 메소드 객체 내부
    • 클래스의 접근 제한
      • 클래스가 어떤 접근 제한을 갖느냐에 따라 사용 가능 여부가 결정됨.
      • 클래스는 public, default 접근 제한을 가질 수 있음.
    • 생성자의 접근 제한
      • 생성자가 어떤 접근 제한을 갖느냐에 따라 호출 가능 여부가 결정됨.
      • 생성자는 public, default, private 접근 제한을 가질 수 있음.
    접근 제한자 생성자 설명
    public 클래스(...) 모든 패키지에서 생성자를 호출할 수 있다.
    = 모든 패키지에서 객체를 생성할 수 있다.
      클래스(...) 같은 패키지에서만 생성자를 호출할 수 있다.
    = 같은 패키지에서만 객체를 생성할 수 있다.
    private 클래스(...) 클래스 내부에서만 생성자를 호출할 수 있다.
    = 클래스 내부에서만 객체를 생성할 수 있다.
    • 필드와 메소드의 접근 제한
      • 필드와 메소드가 어떤 접근 제한을 갖느냐에 따라 호출 여부가 결정됨.
      • 필드와 메소드는 public, default, private 접근 제한을 가질 수 있음.
    접근 제한자 필드와 메소드 설명
    public 필드
    메소드(...)
    모든 패키지에서 필드를 읽고 변경할 수 있다.
    = 모든 패키지에서 메소드를 호출할 수 있다.
      필드
    메소드(...)
    같은 패키지에서만 필드를 읽고 변경할 수 있다.
    = 같은 패키지에서만 메소드를 호출할 수 있다.
    private 필드
    메소드(...)
    클래스 내부에서만 필드를 읽고 변경할 수 있다.
    = 클래스 내부에서만 메소드를 호출할 수 있다.

    6.14 Getter와 Setter

    • 객체의 무결성을 유지하기 위해 객체지향 프로그래밍에서는 메소드를 통해 필드에 접근하는 것을 선호함.
      • Setter: 외부에서 객체의 필드에 접근할 때, 메소드가 데이터를 검증해서 유효한 값만 필드에 저장할 수 있음.
        • 메소드 이름: set + 필드 이름(첫 글자 대문자)
      • Getter: 외부에서 객체의 필드를 읽을 때, 메소드가 적절한 값으로 변환해서 리턴할 수 있음.
        • 메소드 이름: get + 필드 이름(첫 글자 대문자)
        • 필드 타입이 boolean인 경우 메서드 이름이 get으로 시작하지 않고 is로 시작함.
    private 타입 fieldName;
    
    // Getter
    public 타입 getFieldName() {
        return fieldName;
    }
    
    // Setter
    public void setFieldName(타입 fieldName) {
        this.fieldName = fieldName;
    }

    6.15 싱글톤 패턴

    • 애플리케이션 전체에서 한 개의 객체만 생성해서 사용하고 싶을 때 싱클톤(Singleton) 패턴을 적용할 수 있음.
      • 생성자를 private 접근 제한하여 외부에서 new 연산자로 생성자를 호출할 수 없음.
      • 외부에서는 싱글톤 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있음.
    public class 클래스 {
    
        // private 접근 권한을 갖는 정적 필드 선언과 초기화
        private static 클래스 singleton = new 클래스();
    
        // private 접근 권한을 갖는 생성자 선언
        private 클래스() {}
    
        // public 접근 권한을 갖는 정적 메소드 선언
        public static 클래스 getInstance() {
            return singleton;
        }
    }
    // 변수1과 변수2가 참조하는 객체는 동일한 객체임.
    클래스 변수1 = 클래스.getInstance();
    클래스 변수2 = 클래스.getInstance();

     

    이 글은 『이것이 자바다』 책을 학습한 내용을 정리한 것입니다.

    '프로그래밍 > Java' 카테고리의 다른 글

    [스터디4] 06. 제네릭  (0) 2025.03.02
    [스터디4] 05. 중첩 선언과 익명 객체  (0) 2025.02.25
    [스터디4] 04. 인터페이스  (1) 2025.02.16
    [스터디4] 03. 상속  (0) 2025.02.09
    [스터디4] 01. 참조 타입  (0) 2025.01.23
    Comments