TIL 2023/10/30 생성자 접근제어자

YEONGDO·2023년 10월 30일

7. 생성자

생성자는 객체가 생성될 때 호출되며 객체를 초기화하는 역할

1) 생성자 선언과 호출

public Car() {} // 선언

...

Car car = new Car(); // 호출
  • 성자는 반환 타입이 없고 이름은 클래스의 이름과 동일
  • new 연산자에 의해 객체가 생성되면서 Car(); 즉, 생성자가 호출

2) 기본 생성자

  • 기본 생성자는 선언할 때 괄호( ) 안에 아무것도 넣지않는 생성자를 의미
  • 모든 클래스는 반드시 생성자가 하나 이상 존재
  • 반대로 단 하나라도 생성자가 선언되어있다면 컴파일러는 기본 생성자를 추가하지 않는다.
  • 만약 클래스에 생성자를 하나도 선언하지 않았다면 컴파일러는 기본 생성자를 바이트코드 파일에 자동으로 추가시켜준다. 따라서 이러한 경우는 기본 생성자 생략이 가능
public class Car {
		public Car(String model) {} // 생성자 선언
		// 생성자가 한개 이상 선언되었기 때문에 기본 생성자를 추가하지 않음.
}

3) 필드 초기화

  • 객체를 만들때 인스턴스마다 다른 값을 가져야 한다면 생성자를 통해서 필드를 초기화 할 수 있다.
  • 반대로 인스턴스 마다 동일한 데이터를 가지는 필드는 초기값을 대입하는 것이 좋다.
  • 주의할 점
    생성자를 통해 필드 값을 초기화 하고 기본 생성자를 작성하지 않았는데 기본 생성자를 호출한다면?
public Car(String modelName, String colorName, double priceValue) {
    model = modelName;
    color = colorName;
    price = priceValue;
}

...

Car car = new Car(); // 오류 발생
  • 한개 이상의 생성자가 존재하기 때문에 컴파일러가 자동으로 기본 생성자를 추가해주지 않기 때문에 기본 생성자가 존재하지 않아 오류가 발생

4) 생성자 오버로딩

  • 생성자를 통해 필드를 초기화 할 때 오버로딩을 적용할 수 있다.
  • 주의할 점
    오버로딩을 할 때 개수, 타입, 순서가 동일한데 매개변수명만 다르게 하는 경우는 오버로딩 규칙에 위배되기 때문에 오류가 발생
public Car(String modelName, String colorName, double priceValue)
public Car(String colorName, String modelName, double priceValue)
  • modelName과 colorName 매개변수의 위치가 다르기 때문에 가능할 것 처럼 보이지만String, String, double : 매개변수의 개수, 타입, 순서가 동일하기 때문에 중복이 불가능

7. this 와 this()

1) this

  • this는 객체 즉, 인스턴스 자신을 표현하는 키워드
  • 객체 내부 생성자 및 메서드에서 객체 내부 멤버에 접근하기 위해 사용될 수 있다.
  • 객체 내부 멤버에 접근할 때 this 키워드가 필수는 아니지만 상황에 따라 필수가 될 수 있다.
public Car(String model, String color, double price) {
    model = model;
    color = color;
    price = price;
}
  • 이처럼 생성자를 선언하는데 매개변수명과 객체의 필드명이 동일할 경우 오류가 발생하지는 않지만 생성자 블록 내부에서 해당 변수들은 객체의 필드가 아닌 가장 가까운 매개변수명을 가리키게 됨으로 자기 자신에게 값을 대입하는 상황에서 this 키워드를 사용하면 해결할 수 있다.
  • 또한 this는 인스턴스 자신을 뜻하기 때문에 객체의 메서드에서 리턴타입이 인스턴스 자신의 클래스 타입이라면 this를 사용하여 인스턴스 자신의 주소를 반환할 수도 있다.

2) this()

  • this(…)는 객체 즉, 인스턴스 자신의 생성자를 호출하는 키워드
  • 객체 내부 생성자 및 메서드에서 해당 객체의 생성자를 호출하기 위해 사용될 수 있다.
  • 생성자를 통해 객체의 필드를 초기화할 때 중복되는 코드를 줄여줌

7. 접근 제어자

제어자는 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여해 준다.

  • 멤버 또는 클래스에 사용, 외부에서 접근하지 못하도록 제한
  • 클래스, 멤버변수, 메서드, 생성자에 사용되고, 지정되어 있지 않다면 default
- `public` : 접근 제한이 전혀 없다.
- `protected` : 같은 패키지 내에서, 다른 패키지의 자손클래스에서 접근이 가능
- `default` : 같은 패키지 내에서만 접근이 가능
- `private` : 같은 클래스 내에서만 접근이 가능

1) 사용가능한 접근 제어자

  • 클래스 : public, default
  • 메서드 & 멤버변수 : public, protected, default, private
  • 지역변수 : 없음

2) 접근 제어자를 이용한 캡슐화 (은닉성)

  • 접근제어자는 클래스 내부에 선언된 데이터를 보호하기 위해서 사용
  • 유효한 값을 유지하도록, 함부로 변경하지 못하도록 접근을 제한하는 것이 필요

3) 생성자의 접근 제어자

  • 생성자에 접근 제어자를 사용함으로 인스턴스의 생성을 제한할 수 있다.
  • 일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치

4) Getter 와 Setter
객체의 무결성 즉, 변경이 없는 상태를 유지하기 위해 접근 제어자를 사용

  • 이때 외부에서 필드에 직접 접근하는 것을 막기 위해 필드에 private, default 등의 접근 제어자를 사용할 수 있다.
  • private 필드를 읽어오거나 저장할 때 Getter 와 Setter 를 사용하여 이를 해결할 수 있다. (헷갈령..)

Getter

public String getModel() {
    return model;
}

public String getColor() {
    return color;
}

public double getPrice() {
    return price;
}

Setter

public void setModel(String model) {
    this.model = model;
}

public void setColor(String color) {
    this.color = color;
}

public void setPrice(double price) {
    this.price = price;
}

느낀점..

역시나 객체지향은 봐도봐도 이해가 안된다. 뭔가 흐름? 객체가 뭐고 이런 건 어느정도 알겠는데 막상 구현을 하려고 하면 뇌가 굳어지는 거 같은..... 팀 과제 또한 끝나면서 내 지식의 부족함을 깨닫는 시간이였던 거 같다. (현타온다..) 팀장님과 팀원분들 같이 과제를 진행하면서 느끼는 것도 많고 배우는 것도 많았다. 그러나 이렇게 하나하나 배우면서 깨달음을 얻고 하루하루 열심히 공부하다보면 언젠가 "저렇게 되고싶다" 라고 느꼈던 사람들의 지식과 실력처럼 무럭무럭 성장해서 존경받는 개발자가 꼭 되고야 말겠다!!!!!!!!!!!!!!!

profile
개발 블로그

0개의 댓글