[스프링 입문을 위한 자바 객체 지향의 원리와 이해] Chapter 4정리

구범모·2023년 7월 13일
0

개구리책

목록 보기
3/6
post-thumbnail

abstract

abstract method

  • 선언부는 있는데 구현부는 없는 메서드.
  • 상속받는 클래스에서, 해당 메서드를 강제로 오버라이딩하게 한다.

abstract class

  • 추상 메서드를 하나 이상 갖고 있는 클래스.(단, 추상 메서드가 없어도 추상 클래스로 선언할 수 있음.)
  • 해당 클래스의 인스턴스를 만들 수 없다.

생성자

생성자 또한 메서드다.

원래는 객체 생성자 메서드 라는 이름을 생성자라고 줄여서 부르는 것 뿐이다.

  • 클래스 내부에서 생성자를 따로 선언해주지 않는다면, 자바 컴파일러가 기본 생성자를 알아서 만들어 준다.
  • 하지만 기본 생성자가 아닌, 인자를 하나 이상 갖는 생성자를 만들어 준다면, 자바 컴파일러는 기본 생성자를 만들어 주지 않는다.(단, 프로그래머가 기본 생성자를 만들어주면 된다.)

Static block

말하기에 앞서, 지금까지 책에서 설명해 주셨을 때는 프로그램이 시작될 때 모든 패키지, 클래스가 스태틱 영역에 로딩된다고 했는데, 실제로는 해당 패키지 또는 클래스가 처음으로 사용될 때 로딩된다고 한다.

그래서 static 블록이란?

🤓 클래스가 스태틱 영역에 배치될 때 실행되는 코드.

클래스가 처음으로 사용될 때 ?

  • 클래스의 정적 속성을 사용할 때
  • 클래스의 정적 메서드를 사용할 때
  • 클래스의 인스턴스를 최초로 만들 때

클래스를 스태틱 영역에 최대한 늦게 올리는 이유

스태틱 영역도 메모리이기 때문에, 최대한 늦게 사용을 시작하고 최대한 빨리 반환하는 것이 메모리 사용 관점에서 효율적이기 때문!

Static block의 역할

클래스가 처음으로 사용될 때(스태틱 영역에 로딩될 때) 실행할 코드를 static block 안에 선언함으로써 사용해야할 로직을 강제한다는 느낌으로 이해했다.

Static block에서 사용할 수 있는 것들

  • static 멤버들.
  • static 블록이 실행될 때에는 해당 클래스의 인스턴스가 존재하지 않기 때문에, 해당 클래스의 인스턴스 멤버에는 접근을 못한다.

실제 static block의 사용 예시

JUnit의 @BeforeClass 어노테이션.

Final

final 키워드는 클래스, 변수, 메서드 모두에 사용 가능하다.

final 클래스

  • 상속을 허락하지 않는다는 의미.

final 변수

  • 변경이 불가능한, 상수가 된다.
  • 정적 상수 : 선언 시 / static 블록 내부에서 초기화가 가능.
  • 객체 상수 : 선언시 / 객체 생성자 / 인스턴스 블록 내부에서 초기화 가능.
  • 지역 상수 : 선언 시 / 해당 지역 내에서 최초 한번 초기화 가능.

인스턴스 블록이란?

🤓 스태틱 블록과 비슷하게, 인스턴스가 생성될 때 실행되는 블록. 인스턴스 변수를 초기화시키는 코드를 작성한다.

final 메소드

  • 상속(오버라이딩)을 금지하겠다는 의미.

instanceof 연산자

  • 만들어져 있는 객체가 특정 클래스의 인스턴스인지 물어보는 연산자.
  • true / false를 리턴한다.
  • 객체 instanceof 클래스 형식으로 사용한다.
  • 인터페이스 / 구현체 관계에도 똑같이 적용 가능하다.

예시

class Animal {

}

class Bird extends Animal {

}

class Dog extends Animal {

}

public class InstanceofPrac {

    public static void main(String[] args) {

        Animal animal = new Animal();
        Bird bird = new Bird();
        Dog dog = new Dog();

        System.out.println(animal instanceof Animal);
        System.out.println(bird instanceof Bird);
        System.out.println(dog instanceof Dog);
        System.out.println(dog instanceof Animal);
        System.out.println(animal instanceof Dog);
    }
}

특이한 점은, 서브 클래스의 객체 instanceof 슈퍼클래스도 true를 반환한다.

package

  • namespace(이름공간)을 만들어 주는 역할.
  • namespace의 필요성 : 같은 이름이지만, 다른 역할을 하는 클래스를 효과적으로 관리하기 위함.
    (ex : 비즈니스 로직에서 고객 사업부 담당에서 Customer 클래스를, 마케팅 사업부 담당에서 Customer 클래스를 동시에 작성할 경우)
  • 클래스의 주체(소유자)를 naming하는 것을 package라고 한다.

interface

  • 멤버 변수 앞에 public static final 키워드가 생략되어 있어서, 쓰지 않아도 되고 써도 된다.
  • 멤버 메서드 앞에 public abstract 키워드가 생략되어 있어서, 쓰지 않아도 되고 써도 된다.

this

  • 객체가 자기 자신을 지칭할 때 사용하는 키워드.
  • 지역 내에서, 지역 변수가 아닌 객체의 멤버에 접근하고 싶을 때 사용.
  • 지역 변수와 객체 변수 / 정적 변수 의 이름이 같은 경우, 지역 변수가 우선순위로 쓰인다.
  • 객체 변수를 사용하고 싶으면, this 키워드 사용
  • 정적 변수를 사용하고 싶으면, 클래스명을 키워드로 사용.

super

  • 슈퍼(상위) 클래스에 접근할 수 있는 키워드.
  • super.super 키워드는 사용 못한다.

추가 내용

객체의 메소드 호출

생성된 객체가 메소드를 호출하면, 객체명.메소드()가 스택 프레임에 추가적으로 할당되어야 할 거 같은데,

실제로는 클래스명.메소드()가 스택 프레임에 할당된다.

이유는 객체가 생성될 때 마다 힙영역에 멤버 메서드의 공간까지 추가 할당해주면, 메모리가 낭비되는 꼴이 되므로, 힙영역에 별도로 멤버 메서드의 공간을 할당해 주지 않고 동일하게 클래스의 메소드를 호출함과 동시에 this 키워드로 메서드를 호출한 객체를 넘긴다고 한다.

profile
우상향 하는 개발자

0개의 댓글