CH6. 클래스 (2)

a.rubz·2022년 12월 29일
0

이것이 자바다

목록 보기
8/15
post-thumbnail
post-custom-banner

📝 정리

인스턴스 멤버 vs 정적 멤버

인스턴스(instance) 멤버 : 객체에 소속된 멤버 - 객체를 생성해야만 사용 가능

정적(static) 멤버: 클래스에 고정된 멤버 - 객체 없이도 사용 가능


인스턴스 멤버

  • 객체에 소속된 멤버 (객체가 있어야 사용 가능)
  • 우리가 쓰는 대부분의 객체로부터 만든 인스턴스의 필드와 메소드
  • 외부에서 사용 => 객체 생성 후, 참조 변수로 접근
  • 객체의 메소드는 인스턴스 멤버이지만, 객체에 포함되지 않음
  • 메소드 코드는 메소드 영역에 두고 인스턴스끼리 공유해서 사용


this

  • 객체 내부에서 인스턴스 멤버에 접근하기 위해 사용
  • 인스턴스 필드임을 강조하고자 할 때 사용

정적 멤버 (static member)

  • 필드, 메소드에 static => 정적 멤버
  • 자바는 클래스 로더를 사용해 클래스를 메소드 영역에 저장하고 사용
  • 정적멤버는 메소드 영역의 클래스에 고정적으로 위치하는 멤버
  • 객체 생성 없이 클래스를 통해 바로 사용 가능 => 클래스 이름 + 도트(.) 연산자로 접근
  • 객체 참조 변수로도 접근 가능
  • 객체마다 가질 필요 없는 공용적인 필드, 인스턴스 필드를 이용하지 않는 메소드 => 정적 멤버로
  • 정적 메소드와 정적 블록은 인스턴스 필드, 인스턴스 메소드, this 사용 불가 => 객체 생성 후, 사용 가능

정적 블록

  • 복잡한 초기화 작업이 필요할 때 이용
public class Car {
    static String company = "현대";
    static String model = "그랜저";
    static String info; // 현대-그랜저
    
    static {
        info = company + "-" + model;
    }
}


final 필드와 상수 : 값을 변경하는 것을 막고 읽기만 허용할 때 사용

final 필드

final 타입 필드 [= 초기값];
  • final => 최종적
  • 초기값이 저장 => 최종값으로 수정 불가
  • 필드 선언 시에 초기값 대입
  • 생성자에서 초기값 대입
  • 초기값 대입을 안 하고 final 필드를 그대로 두면 컴파일 에러

상수 (constant)

static final 타입 상수 [= 초기값];
  • 불변의 값을 저장하는 필드
  • 예) 원주율, 지구의 무게, 둘레 ...
  • 객체마다 저장할 필요 없음, 여러 개의 값을 가져도 안 됨 => static + final
  • 정적블록에서 초기화 가능
  • 상수 이름은 모두 대문자, 언더바(_)로 단어 연결


static vs final vs static final

의미사용
static고정된객체 생성 없이 사용할 수 있는 필드와 메소드를 생성하고자 할 때
객체마다 가질 필요가 없는 공용으로 사용하는 필드(공용 데이터)가 필요할 때
인스턴스 필드를 포함하지 않은 메소드가 필요할 때
final최종적인수정이 불가능한 값을 갖고 싶을 때
static final고정된 + 최종적인상수를 선언할 때
객체마다 저장할 필요 없이(static) + 단 하나의 값만 가질 때(final))

[참고] https://gobae.tistory.com/3



✔ 패키지

  • 자바에선 단순히 디렉토리 X
  • 클래스의 일부분이자 클래스를 식별하는 용도로 사용
  • 도트(.)로 상위, 하위 패키지 구분

✔ 패키지 선언

package 상위패키지.하위패키지;
  • 패키지명 모두 소문자

✔ import 문

  • 다른 패키지에 있는 클래스를 사용하기 위해 이용

  • 패키지 선언과 클래스 선언 사이에 작성

  • *를 통해 패키지에 포함된 다수의 클래스 사용 가능

  • 하위 패키지를 포함하지 않아서 하위패키지의 클래스 사용 시, 따로 import문 작성

    import com.rubi.*;
    import com.rubi.project.*;
  • 서로 다른 패키지에 동일한 클래스 이름이 있을 경우, 컴파일 에러

    // rubi1의 Rubi
    package com.rubi1;
    
    public class Rubi{...}
    // rubi2의 Rubi
    package com.rubi2;
    
    public class Rubi{...}
    package com.rubi3;
    
    import com.rubi1.*;
    import com.rubi2.*;
    
    public class Velog {
        Rubi rubi = new Rubi(); // 컴파일 에러, 어떤 패키지의 Rubi인지 알 수 없음
    }
    package com.rubi3;
    
    public class Velog {
        com.rubi1.Rubi rubi = new com.rubi1.Rubi(); // import없이 클래스 전체 이름 사용
    }


접근 제한자 (Access Modifier)

  • 객체의 무결성 유지를 위해 필드와 메소드를 외부에 노출하지 않도록 함

  • 객체의 필드를 외부에서 변경하거나 메소드를 호출할 수 없도록 함

  • 접근 제한자제한 대상제한 범위
    public클래스, 필드, 생성자, 메소드없음
    protected필드, 생성자, 메소드같은 패키지, 자식 객체만 사용 가능
    (default) : 생략 가능클래스, 필드, 생성자, 메소드같은 패키지
    private필드, 생성자, 메소드객체 내부


✔ Getter와 Setter

  • OOP는 직접적인 외부에서의 필드 접근을 막음
  • 대신 메소드를 통해 필드에 접근하는 것을 선호

Getter

  • 외부에서 객체의 필드를 읽을 때 메소드 필요
  • 필드값을 적절한 값으로 변환해서 리턴 가능
  • 필드 타입이 boolean일 경우, is로 시작하는 것이 관례

Setter

  • 외부에서 객체의 필드를 수정, 저장할 때 메소드 필요
  • 데이터를 검증해서 유효한 값만 필드에 저장


싱글톤 패턴 (Singleton Pattern)

  • 애플리케이션 전체에서 단 한 개의 객체만 생성해 사용할 경우
  • 생성자를 private 접근 제한
  • 외부에서 new 연산자로 생성자를 호출할 수 없도록 함
  • 정적 메소드를 통해 간접적으로 객체를 얻음
public class 클래스 {
    //private 접근 권한을 갖는 정적 필드 선언과 초기화
    private static 클래스 singleton = new 클래스();
    
    //private 접근 권한을 갖는 생성자 선언
    private 클래스() {}
    
    //public 접근 권한을 갖는 정적 메소드 선언
    public static 클래스 getInstance() {
        return singleton;
    }
}

✔ 싱글톤 패턴은 언제 사용할까?

(예시1)

프로그램 내부에서 발생하는 이벤트들을 스케쥴링 하고 처리하는 객체

=> 모든 이벤트는 하나의 같은 스케쥴링 큐에 들어가서 처리되어야 함

=> 이벤트마다 스케쥴링 큐를 따로 생성하면 설계 의도와 어긋남


(예시2)

안내 음성

=> 안내 음성은 애플리케이션 내부에서 항상 한 번에 하나의 음성만 출력되어야 함

=> 동시에 여러 개의 음성이 겹쳐서 출력되지 않게 구현해야 함

=> 안내 음성을 관리하고 출력하는 객체가 프로그램 내부에서 단 하나만 존재하도록!

=> 기존에 음성이 나오는 상황에서 다른 음성이 나오는 기능을 동작할 경우

=> 기존의 음성을 정지하고 다른 음성이 나와야 함

[참고] https://injae-kim.github.io/dev/2020/08/06/singleton-pattern-usage.html



💡 스터디

profile
🔥 개발 공부 🔥
post-custom-banner

0개의 댓글