[Java 기본]Section 4 - 생성자

우영·2024년 2월 2일

JAVA 기본편

목록 보기
4/13

생성자란? - 필요한 이유

  • 생성자는 객체 생성 직후 객체를 초기화 하기 위한 특별한 메서드로 생각
package construct;
public class MemberInit {
 String name;
 int age;
 int grade;
}
package construct;
public class MethodInitMain1 {
 public static void main(String[] args) {
 MemberInit member1 = new MemberInit();
 member1.name = "user1";
 member1.age = 15;
 member1.grade = 90;
 MemberInit member2 = new MemberInit();
 member2.name = "user2";
 member2.age = 16;
 member2.grade = 80;
 MemberInit[] members = {member1, member2};
 for (MemberInit s : members) {
 System.out.println("이름:" + s.name + " 나이:" + s.age + " 성적:" +
s.grade);
 }
 }
}

  • 회원 객체를 생성하고 나면 name, age, grade 같은 변수에 초기값을 설정한다. 아마도 회원 객체를 제대로 사용하기 위해서는 객체를 생성하자 마자 이런 초기값을 설정.

하지만 이 코드는 초기값을 설정하는 부분이 계속 반복

  • 메서드를 사용해서 반복 제거
package construct;
public class MethodInitMain2 {
 public static void main(String[] args) {
 MemberInit member1 = new MemberInit();
 initMember(member1, "user1", 15, 90);
 MemberInit member2 = new MemberInit();
 initMember(member2, "user2", 16, 80);
 MemberInit[] members = {member1, member2};
 for (MemberInit s : members) {
 System.out.println("이름:" + s.name + " 나이:" + s.age + " 성적:" +
s.grade);
 }
 }
 static void initMember(MemberInit member, String name, int age, int grade) {
 member.name = name;
 member.age = age;
 member.grade = grade;
 }
}

This

  • 본인한테 가까운 거 먼저 찾고 없으면 멤버변수 찾는방식.
package construct;
public class MemberInit {
 String name;
 int age;
 int grade;
 //추가
 void initMember(String name, int age, int grade) {
 this.name = name;
 this.age = age;
 this.grade = grade;
 }

package construct;
public class MethodInitMain3 {
 public static void main(String[] args) {
 MemberInit member1 = new MemberInit();
 member1.initMember("user1", 15, 90);
 MemberInit member2 = new MemberInit();
 member2.initMember("user2", 16, 80);
 MemberInit[] members = {member1, member2};
 for (MemberInit s : members) {
 System.out.println("이름:" + s.name + " 나이:" + s.age + " 성적:" +
s.grade);
 }
 }
}
  • initMember의 코드를 보면 메서드의 매개변수에 정의한 String name과 Member의 멤버 변수의 이름이 String name으로 둘다 똑같다.
  • 나머지 name, age, grade로 모두 같다.

멤버 변수와 메서드의 매개변수의 이름이 같으면 둘을 어떻게 구분해야 할까?

  • 멤버 변수보다 매개변수가 코드 블럭의 더 안쪽에 있기 때문에 매개변수가 우선순위를 가진다.
  • 멤버 변수에 접근하려면 앞에 this.이라고 해주면 된다.

    여기서 this는 인스턴스 자신의 참조값을 가리킨다.

this의 생략

  • 가까운 지역변수(매개변수도 지역변수다)를 먼저 찾고 없으면 그 다음으로 멤버 변수를 찾는다.(멤버 변수가 없을 시 오류 발생)

익숙하지 않은 것

  • 크게 멤버 변수, 지역 변수로 나누어지고, 멤버변수는 클래스변수와 인스턴스 변수로 나누어 진다.
  1. 멤버 변수 : 선언위치가 '클래스영역'
  2. 지역변수 : 선언위치 '메소드나 생성자 내부', 정의는 '메서드 내에 선언되어 메서드 내에서만 사용이 가능한 변수'
  • 메소드: '프로그램이 어떤 동작을 하게 하는 명령 기능', 영어와 관련지어 '동사'에 해당. sout와 같이 JAVA에서 제공하지만, 개발자가 직접 만들어 사용 가능

  • 멤버변수 - 클래스변수, 인스턴스 변수

  1. 클래스 변수 : 모든 객체가 공톡적으로 똑같은 속성을 가질 때 사용
  2. 인스턴스 변수 : 각각의 객체(인스턴스)마다 개별적인 속성을 가질 때 사용
    ex)
package construct;
public class MemberThis {
 String nameField;
 void initMember(String nameParameter) {
 nameField = nameParameter;
 }
}
  • nameField는 앞에 this가 없어도 멤버 변수에 접근한다.
    (nameField = this.nameField)
  • nameParameter는 먼저 지역변수(매개변수)에서 같은 이름이 있는지 찾는다. 이 경우 매개변수가 있으므로 매개변수를 사용한다.

this와 코딩 스타일

  • 멤버 변수에 접근하는 경우에 항상 this를 사용하는 코딩 스타일도 있다. 위의 코드에 nameField를 this.nameField라고 적는 것이다.
    이렇게 쓸 시 이 코드가 멤버 변수를 사용하는 것을 눈으로 쉽게 확인 가능하다. 그래서 과거에 많이 사용되었다. 쉽게 말해서 this를 강제로 사용해서, 지역 변수와 멤벼 변수를 눈에 보이도록 구분하는 것
    하지만 IDE가 발전하면서 멤버 변수와 지역 변수를 색상으로 구분해준다.

생성자

  • 객체를 생성하고 바로 초기값을 할당해야 하는 경우가 많다. 그래서 대부분의 객체 지향 언어는 객체를 생성하자마자 즉시 필요한 기능을 좀 더 편리하게 수행할 수 있도록 생성자라는 기능을 제공한다.
  • 생성자를 사용하면 객체를 생성하는 시점에 즉시 필요한 기능을 수행할 수 있다.

package construct;
public class MemberConstruct {
 String name;
 int age;
 int grade;
 MemberConstruct(String name, int age, int grade) {
 System.out.println("생성자 호출 name=" + name + ",age=" + age + ",grade=" +
grade);
 this.name = name;
 this.age = age;
 this.grade = grade;
 }
}

  • 이 부분이 생성자이다.
    - 생성자는 메서드와 유사하지만 차이가 있다.
    • 생성자의 이름은 클래스 이름과 같아야 한다. 따라서 첫 글자도 대문자로 시작
    • 생성자는 반환 타입이 없다. 비워야 된다.
    • 나머지는 메서드와 같다.

생성자 호출

생성자는 인스턴스(객체)를 생성하고 나서 즉시 호출된다.

  • 방법

생성자 장점

  • 중복 호출 제거
    • 생성 후 처리까지 한번에 처리할 수 있게 되었다.
  • 제약(생성자 호출 필수)
    • 실수로 호출하지 않아도 프로그램이 작동한다 하지만 데이터가 없는 상태로 프로그램이 작동된다. 만약에 값들을 필수로 반드시 입력해야 한다면 시스템에 문제가 발생할 수 있다.

생성자의 진짜 장점은 객체를 생성할 때 직접 정의한 생성자가 있다면 직접정의한 생성자를 반드시 호출해야 한다는 점이다. 참고로 생성자를 메서드 오버로딩 처럼 여러개 정의할 수 있는데, 이 경우에는 하나만 호출하면 된다.

기본 생성자

  • 기본 생성자 : 매개변수가 없는 생성자
  • 클래스에 생성자가 하나도 없으면 자바 컴파일러는 매개변수가 없고, 작동하는 코드가 없는 기본 생성자를 자동으로 만들어준다.
    - 생성자가 하나라도 있으면 자바는 기본 생성자를 만들지 않는다.

생성자 - 오버로딩과 this()

  • 생성자도 메서드 오버로딩처럼 매개변수만 다르게 해서 여러 생성자를 제공할 수 있다.


this()

두 생성자를 보면 중복하는 부분이 있다.

이때 this() 라는 기능을 사용하면 생성자 내부에서 자신의 생성자를 호출할 수 있다. 참고로 this는 인스턴스 자신의 참조값을 가리킨다. 그래서 자신의 생성자를 호출한다고 생각하면 된다.

생성자 중복피하기(이해 하는데 오래걸림)

  • 다른 생성자를 호출해서 자기의 값으로 초기화(예를 들어 메소드를 호출하는 것처럼)

문제


package construct.ex;

import java.awt.*;

public class Book {
 String title; //제목
 String author; //저자
 int page; //페이지 수

 Book(){//기본 생성자
  this("", "", 0);
 }
 // title과 author만을 매개변수로 받는 생성자
 Book(String title, String author){
  this(title,author,0);
 }
  // 모든 필드를 매개변수로 받는 생성자
 Book(String title, String author, int page){
  this.title = title;
  this.author = author;
  this.page = page;
 }
 void displayInfo(){
  System.out.println("제목: " + title + ", 저자:" + author +  ", 페이지:" + page);
 }
}

방식

1. 2개를 먼저 만들어준다. 이렇게

2. void displayInfo() {
System.out.println("제목: " + title + ", 저자: " + author + ", 페이지: " +
page);
}
} 이 줄을 넣어서 출력을 완료해준다.

0개의 댓글