본문 바로가기

코딩 국비 학원/Do it! 자바 프로그래밍 입문

[Do it! 자바 프로그래밍 입문]생성자, 참조 자료형, 정보 은닉

22.12.05 배운 내용 정리
(생성자, 참조 자료형, 정보 은닉)

 

생성자

 

※ 생성자 만들기 & 생성자 테스트 하기

 

 

위 예제에서 자바에서 클래스를 생성할 때 사용하는 Person( ) 같은 함수를 생성자라고함.

클래스의 멤버 변수는 메서드에 의해 값이 변경될 수도 있지만, 처음 클래스를 생성할 때 값을 정해야 하는 경우도 있음.

생성자가 하는 일클래스를 처음 만들 때 멤버 변수나 상수를 초기화하는 것임.

 

※ 디폴트 생성자

 

생성자는 클래스를 생성할 때만 호출함. 생성자 이름은 클래스 이름과 같고, 생성자는 반환 값이 없음.

생성자가 없는 클래스는 클래스 파일을 컴파일할 때 자바 컴파일러에서 자동으로 생성자를 만들어줌.

이렇게 자동으로 만들어주는 생성자디폴트 생성자(default constructor)라고 함.

디폴트 생성자는 매개변수와 구현 코드가 없으며, 프로그래머가 디폴트 생성자를 직접 만드는 경우에는

필요에 따라 직접 코드를 구현할 수 있음.

 

디폴트 생성자

 

생성자 만들기

 

생성자 = 주로 멤버 변수에 대한 값들을 매개변수로 받아서 인스턴스가 새로 생성될 때

멤버 변수 값들을 초기화하는 역할을 함.

즉 인스턴스가 생성됨과 동시에 멤버변수의 값을 지정하고 인스턴스를 초기화하기 위해 생성자를 직접 구현하여 사용함.

 

※ Person 클래스를 생성할 때 이름을 매개변수로 받는 생성자 구현 & 테스트

 

생성자 구현
생성자 테스트(오류 발생)

 

PersonTest 코드에서 오류가 발생한 이유 = 생성자를 직접 구현하여 디폴트 생성자가 없기 때문.

자바 컴파일러는 생성자가 하나도 없는 경우에만 디폴트 생성자를 제공함.

즉 프로그래머가 생성자를 직접 추가하면 디폴트 생성자는 만들어지지 않는다는 것임.

오류를 없애는 방법 = 매개변수가 있는 생성자로 호출하거나, 프로그래머가 디폴트 생성자를 추가 구현

 

※ 오류를 없애기 위해 디폴트 생성자 직접 추가

 

 

이렇게 디폴트 생성자를 직접 추가하면 PersonTest.java 파일을 실행했을 때 더 이상 오류가 발생하지 않음.

그리고 이제 Person 클래스를 생성할 때 두 생성자 중 하나를 선택해 사용할 수 있음

① 디폴트 생성자로 클래스 생성

② 이름을 매개변수로 받아 클래스 생성

 

생성자 오버로드

 

생성자 오버로드(constructor overload) = 클래스에 생성자가 두 개 이상 제공되는 경우로,

필요에 따라 매개변수가 다른 생성자를 여러 개 만들 수 있음.

클래스에 생성자를 여러 개 제공하면 이 클래스를 사용하는 코드에서는 원하는 생성자를 선택해 사용 가능함.

경우에 따라서는 클래스에서 일부러 디폴트 생성자를 제공하지 않기도 함.

 

ex. 학생이 생성될 때는 반드시 학번이 있어야 한다면 다음처럼 생성자를 제공할 수 있음.

      public class Student {

      int studentID;

   

      public Student(int studentID) {        //학번을 매개변수로 입력받아 Student 클래스를 생성하는 생성자

           this.studentID = studentID;        //this = 생성된 인스턴스 스스로를 가리키는 예약어

        }

    }

이러한 경우에 항상 학번을 사용하여 Student 클래스를 생성할 수 있고, 디폴트 생성자를 구현하지 않음.

그 이유는 학생이 생성될 때 학번이 꼭 필요하기 때문. 즉 매개변수가 있는 생성자를 추가한다고 해서

프로그래머가 꼭 디폴트 생성자를 추가로 작성해야 하는 것은 아님

 

※ 생성자 사용

 

 

※ 테스트 클래스 구현

 

 


 

참조 자료형

 

크기가 정해진 기본 자료형(int, char, float, double 등)으로 선언하는 변수가 있고,

클래스 자료형으로 선언하는 참조 자료형 변수가 있음.

 

※ 국어 성적과 수학 성적 정보를 저장하는 프로그램을 만드는 경우

① 우선 클래스를 어떻게 만들지 생각해야함.(클래스가 제공해야 할 멤버 변수와 메서드 생각하기)

 

학생 클래스 만들기(1)

 

여기에서 StringJDK에서 제공하는 참조 자료형이며, 나머지 변수는 기본 자료형임.

 

여기서 성적을 저장하는 변수가 두 개(int KoreaScore, int mathScore)있는데,

만약 성적뿐만 아니라 이 학생이 수강하는 과목의 이름도 함께 저장해야 할 경우String 사용, 과목 이름 변수 추가 

 

학생 클래스 만들기(2)

 

이 클래스는 학생에 대한 클래스인데 과목에 대한 변수가 늘어나고 있음

해결방법 : 과목의 이름과 성적을 Subject라는 클래스로 분리하고, 학생에 Subject 변수를 각 과목별로 추가

 

과목 클래스 만들기
학생 클래스 만들기(3)

 

※ 이러한 방식으로 구현함으로써 달라진점

→ 기존의 Student 클래스에 과목이름을 추가해야 할 때 원래는

koreanSubjectName, mathSubjectName 이렇게 두 개의 변수를 추가해야 함.

하지만 Subject로 클래스를 분리하면 subjectName은 Subject 클래스에 선언하면하기만 하면되고,

국어 과목 이름은 korean.subjectName으로, 수학 과목 이름은 math.subjectName으로 사용할 수 있어 편리함.

 


 

접근 제어자

 

접근 제어자(access modifier) = 예약어

ex. public 예약어 = public이라고 선언한 변수나 메서드는

외부 클래스에서 접근이 가능하며 외부 클래스가 사용할 수 있다는 뜻임.

ex. private 예약어 = private라고 선언한 변수나 메서드는 외부 클래스에서 사용할 수 없다는 뜻임.

 

※ private 사용하기

 

 

→ studentName 변수를 private로 선언함.

 

※ private 변수 테스트하기

 

 

→ 7행에 오류 발생 = studentName 변수의 접근 제어자가 public일 때는 외부 클래스인 StudentTest.java 클래스에서

이 변수에 접근할 수 있었지만 private으로 바뀌면서 외부 클래스의 접근이 허용되지 않기 때문

 

get(), set() 메서드

 

get(), set() 메서드 = private으로 선언한 변수를 외부 코드에서 사용할 수 있는 방법

 

※ get(), set() 메서드 사용하기

 

 

public get() = private 변수인 studentName에 접근해 값을 가져옴

public set() = private 변수인 studentName에 접근해 값을 지정함

 

※ private 변수에 접근하기

다음과 같이 StudentTest.java 파일을 수정하면 private 변수에 접근가능

 

 

→ studentLee.studentName = "이상원";에서 studentLee.setStudentName("이상원");으로 수정하면

private 변수에 접근 가능해짐.

 

※ get(), set() 메서드 자동으로 만들기

① 선언한 클래스 내부에서 오른쪽 마우스 클릭

② [Source → Generate Getters and Setters...] 메뉴 클릭

③ get(), set() 메서드를 추가하고 싶은 멤버 변수 선택 후 Generate 버튼 클릭

 

 

정보 은닉

 

변수를 public으로 선언하는 것과

변수를 private로 선언하고 나서 그 변수를 사용할 수 있도록 public 메서드를 제공하는 것의 차이

public class MyDate {

   public int date;

   public int month;

   public int year;

}

앞 코드에서 Mydate 클래스를 보면 Mydata 클래스의 day, month, yer을 모두 public으로 선언했음.

따라서 외부 클래스에서 Mydata를 사용할 때 값을 마음대로 넣을 수 있음.

그리고 이 클래스를 사용한 다음 코드를 보면 2월은 28일이나 29일까지이데 31일로 대입되었음.

 

public class MyDateTest {

  public static void main(String[ ] args) {

    MyDate date = new MyDate( );

    date.month = 2;

    date.day = 31;

    date.year = 2018;

  }

}

클래스의 멤버 변수를 public으로 선언하면 접근이 제한되지 않으므로 정보의 오류가 발생할 수 있음.

이런 경우에는 오류가 나더라도 그 값이 해당 변수에 대입되지 못하도록 다음과 같이

변수를 private으로 바꾸고 public 메서드를 별도로 제공해야 함.

 

Public class MyDate [

    private int day;

    private int month;

    private int year;

 

    public noid setDay(int day) {

        if(month == 2)  {

           if(day < 1 || day > 28) {

              System.out.println("오류입니다");

           } else  {

             this.day = day;

           }

       }

    }

}

※ 윤년(2월 29일) 고려X

 

이처럼 클래스 내부에서 사용할 변수나 메서드는 private으로 선언해서 외부에서 접근하지 못하도록 하는 것

객체 지향에서는 '정보 은닉(information hiding)'이라고 함.

정보 은닉은 객체 지향 프로그래밍의 특징 중 하나이며 자바에서는 접근 제어자를 사용하여 정보 은닉을 구현함.

모든 변수를 private으로 선언해야 하는 것은 아니지만, 필요한 경우에는 private으로 선언하여 오류를 막을 수 있음.

 

※ 자바에서 사용하는 접근 제어자

 

접근 제어자 설명
public 외부 클래스 어디에서나 접근 가능
protected 같은 패키지 내부와 상속 관계의 클래스에서만 접근할 수 있고 그 외 클래스에서는 접근할 수 없음.
아무것도 없는 경우 default이며 같은 패키지 내부에서만 접근 가능
private 같은 클래스 내부에서만 접근 가능

 


 

5장 연습문제 풀이

 

① 클래스를 생성할 때 호출하는 OOO는 멤버 변수를 초기화하는데 사용함.

생성자

 

② 클래스를 생성하여 메모리에 있는 상태를 OOOO라하고, 멤버 변수를 다른 말로 OOOO OO라고 함.

인스턴스, 인스턴스 변수

 

③ OOO는 일반 함수에 객체 지향의 개념을 추가하여, 클래스 내부에 선언하고 클래스 멤버 변수를 사용하여 클래스 기능을 구현함.

메서드

 

④ 05-7예제 MyDate와 MyDateTest 클래스 완성하기

 

MyDate 클래스

 

※ Public boolean isValid() 메서드를 반환(return)하면 그 값은 true 아니면 false 가 출력되어야 함.

 

MyDateTest 클래스