Java-4 : 자바가 확장한 객체 지향

박건희·2021년 11월 9일
0

1. Abstract 키워드

  • 추상 메서드와 추상 클래스를 선언할 때 사용하는 키워드
  • 추상 메서드 : 구현부가 없는 메서드
  • 추상 클래스 : 추상 메서드를 1개이상 가지는 클래스

2. 추상 클래스

  • 추상 클래스로 부터는 인스턴스를 생성할 수 없다.
  • 추상 클래스를 상속한 클래스는 추상 메서드를 반드시 오버라이딩 해야한다.

3. 생성자

  • new 클래스()로 클래스의 인스턴스를 생성한다.
  • 생성자의 다른 이름은 "객체 생성자 메서드"이다.(반환형은 void)
  • 기본 생성자
    • 자바 컴파일러는 클래스에 생성자가 없으면 기본 생성자(noargconstruct)를 만들어줌
    • 기본 생성자가 호출되면 인스턴스 변수들은 각자의 기본값으로 초기화됨(int:0, String:"", Class: null)
    • 프로그래머가 생성자를 만들어주면(생성자 오버로딩) 기본 생성자를 만들지 않음
  • 상속 관계에서 자식 클래스의 생성자에서는 부모클래스의 생성자가 가장 먼저 호출된다.

4. static 블록

  • 객체 생성자가 있다면, 클래스 생성자도 있다
  • static {} 블록은 클래스가 처음 사용되는 시점에 메모리의 스태틱 영역에 로드된다
    • 보통 프로그램 실행시 클래스 정보가 로드된다고 알려져 있는데 이는 잘못된 정보
    • 클래스(static)영역의 자원은 프로그램이 종료될 때 반환되므로, 최대한 늦게 로드하는 것이 이득
  • 클래스가 사용(로드)되는 시점
    • 클래스 변수가 사용될 때
    • 클래스 메소드가 사용될 때
    • 클래스 인스턴스가 생성될 때
  • static 블록에서 사용할 수 있는 멤버는 static 멤버(static 블록이 로드되는 시점에는 객체 멤버는 메모리상에 없다)
  • static 변수와 마찬가지로, 모든 클래스가 공유하는 영역이므로 클래스가 최초 로드되는 시점에 한번만 실행된다
  • 사용예
    • @BeforeClass (JUnit 4), @BeforeAll (JUnit 5)
      test실행전에 공통적으로 수행해야 하는 작업
  • 참고 : 인스턴스 블록 {}
    • 인스턴스가 생성될 때마다 {} 내용이 실행됨
    • 생성자 실행 전에 실행됨

5. final 키워드

  • final Class
    • 상속의 대상이 되지 않는 Class
    • 해당 Class를 확장(extends) 할 수 없음
  • final Variable
    • 상수 : 불변 값을 갖는 변수
    • 최초 1회만 초기화 가능
    • 인스턴스 변수는 선언후 생성자에서 초기화 가능
  • final Method
    • override를 허용하지 않는 메서드

6. instanceof 연산자

  • 객체가 특정 클래스(인터페이스)의 인스턴스인지 확인
  • 참조변수 instanceof 클래스(인터페이스)
    참조변수의 타입이 결정하는 것이 아니라, 실제 객체의 타입(new 연산자를 적용한 클래스/인터페이스)이 결정한다
  • 주의점
    • instanceof연산자를 많이 사용하는 코드는 LSP(리스코프 치환원칙)을 어기고 있는지 확인해봐야 한다

7. package 키워드

  • 이름공간 namespace
    • 하나의 프로젝트의 같은 이름의 클래스가 여러개 있으면 충돌 발생
    • c++의 namespace 처럼 이름공간을 나누어서 충돌을 피하게 함

8. interface와 implements

  • 인터페이스는 기본적으로 public abstract method와 public static final 변수만 가진다
  • public abtract/public static final 은 컴파일러가 자동으로 추가해줘서 생략이 가능함
  • 자바8 이후
    • 구현부가 있는 default 메소드를 가질 수 있다
    • staic 메소드를 가질 수 있다
    • Lambda
      • 빅데이터와 병렬성을 위해 등장
      • 변수에 함수를 저장
      • 변수는 메소드의 인자, 반환값으로도 사용 가능

9. this 키워드

  • 객체 자신을 지칭하는 키워드
  • this로 같은 이름의 지역변수와 인스턴스 변수를 구분할 수 있음

10. super 키워드

  • 상위 클래스의 인스턴스를 지칭하는 키워드
  • super.super 형태는 불가

11. 인스턴스 메소드에 대한 오해

  • 객체 정보는 매 객체 생성마다 heap영역에 할당하는 것으로 알고 있는데,
  • 인스턴스 메소드는 static 영역에 로드된다
  • 그래서 인스턴스 메소드 호출시,
    객체 변수.메서드 (X)
    클래스명.메서드(O)
    의 형태가 된다
  • JVM 내부에선, static 영역에 로드되는 인스턴스 메서드에 this를 파라미터로 넘긴다

이렇게 되는 이유는 인스턴스 메소드는 인스턴스 메소드를 호출하는 객체의 인스턴스 변수의 값이 다를뿐, 메서드 자체가 달라지는 것이 아니므로 static 영역에 보유하면 메모리를 절약할 수 있다.

12. import 키워드

  • 다른 패키지의 클래스를 사용하기 위한 키워드
  • 컴파일타임에 컴파일러가 import된 클래스의 패키지를 알아내서, 모든 클래스이름 앞에 패키지명을 붙여줌
  • import 패키지명.*; 은 패키지에 속하는 모든 클래스를 패키지명 없이 사용 가능
    • 클래스이름을 지정하는 것보다 컴파일 타임이 약간 더 걸리지만,
      실행상의 성능 차이는 없다
    • .*로 import 해도 하위 패키지의 클래스를 import 하는 것은 아니다
  • static import
    • 다른 패키지의 클래스의 static 멤버를 사용할 때, 클래스명 생략 가능
    • Math.random() / random()

0개의 댓글