-
생성자(Constructor) & 기본 클래스 만들기JAVA/Class 2020. 10. 21. 22:26
모든 클래스는 인스턴스화 될 때, 생성자를 사용한다.
생성자의 특징
1. 생성자는 리턴타입이 없다.
2. 생성자를 프로그래머가 만들지 않으면 매개변수가 없는 생성자가 컴파일할 때, 자동으로 만들어진다.
이 매개변수가 없는 생성자를 기본생성자라고 한다.
3. 생성자를 하나라도 프로그래머가 만들었다면 기본생성자는 자동으로 만들어지지 않는다.
생성자의 역할
. 생성자가 하는 일은 객체가 될 때, 초기화 하는 역할을 수행한다.
생성자에서는 초기화의 역할을 할 수도 있으며, 생성자도 함수이므로 오버로딩이 가능함을 알 수 있다.
Person이라는 클래스를 하나 만들어보자.
생성자는 4개를 만들어 보았다.
다음과 같다.
그런데 위의 내용을 다음과 같이 작성 가능하다.
위와 내용과 아래의 내용은 모두 같다.
그리고, 위의 내용에서 필드는 2개 뿐이다.
이 필드를 저장하고 내보내는 함수들을 각 각 만들어 보자.
즉, Get, Set함수들을 각 각 만들어보자.
그리고, Person클래스의 이름과 나이를 출력하는 함수들을 만들어보자.
만들어 놓은 클래스를 인스턴스화(객체화) 해서 각 객체들의 정보를 출력해보자.
프로그램 실행결과
소스 코드
더보기class Person { private String name; private int age; // 1번 생성자가 4번 생성자를 호출 public Person(){this(null,0);} // 2번 생성자가 4번 생성자를 호출 public Person(String name) {this(name,0);} // 3번 생성자가 4번 생성자를 호출 public Person(int age) {this(null,age);} // 4번 생성자 public Person(String name, int age) { this.name = name; this.age = age; } public String GetName() {return this.name;} public int GetAge() {return this.age;} public void SetName(String name) {this.name = name;} public void SetAge(int age) {this.age = age;} public void ShowName() {System.out.println("이름 : "+this.name);} public void ShowAge() {System.out.println("나이 : "+this.age);} public void ShowAllInfo() { this.ShowName(); this.ShowAge(); } public void ShowTHIS(){System.out.println(this);} } public class PersonTest { public static void main(String[] args) { Person p1 = new Person("lee",20); p1.ShowAllInfo(); Person p2 = new Person(); p2.SetName("kim"); p2.SetAge(30); p2.ShowAllInfo(); } }
이번에는 성적에 대한 클래스를 만들어보자.
필드부터 정의하자. 과목의 수는 변하지 않는다는 조건 하에 final 지시 예약어를 이용했다.
subjectCnt는 3으로 초기화 동시에 상수가 되었다.
생성자를 정의해보자. 생성자는 여러 개를 정의할 수 있지만, 위에서 여러 번 정의 했으므로 하나만 하자.
총점과 평균은 외부에서 입력받을 필요 없다.
과목 점수가 입력되면 그 때 변하는 필드들이다.
그리고, 나중에 각 과목점수들이 변경이 될 수 있다.
그러면 그에 따른 총점과 평균이 달라지기 때문이다. 이 평균과 총점을 구하는 함수들을 정의해보자.
아래와 같이 세 함수를 정의한 이유는 다음과 같다.
총점을 구한 이후에 평균을 구하는 것이 일반적인 순서이다.
그런데 실수로 평균을 먼저 구하고 총점을 그 이후에 구하는 실수를 줄이기 위해서
CalTotAndAvg함수 하나만 호출해서 총점과 평균을 같이 구하도록 한다.
평균과 총점은 서로 뗄 수 없는 관계라서 이와 같이 정의했다.
그리고 CalTot함수와 CalAvg함수는 접근 제한자가 private임을 볼 수 있다.
이는 외부에서의 호출을 막기 위함이다. 즉, 각 과목들의 점수가 변경이 될 때
그 때 해당 클래스에서만 호출이 되도록 구현한 것이다.
각 과목들의 점수를 저장하는 Set함수를 보자.
각 과목 점수가 변경이 되면, 총점과 평균이 달라지므로 위의 함수를 호출한다.
그리고, 이름과 학번을 Get하고 Set함수를 만들자.
설명은 필요 없을 것 같다.
그리고, 나머지는 각 정보들을 출력하는 함수들이다.
설명은 필요 없을 것 같다.
이제 메인 함수에서 객체화를 하고 정보를 출력해보자.
프로그램 실행결과
s1객체의 수학점수가 변경됨에 따라 총점과 평균도 같이 변했다.
소스 코드
더보기class Sungjuk { private int hakbun; // 학번 private String name; // 이름 private int kor, eng, math; // 과목 점수 private int tot; // 총점 private double avg; // 평균 public static final int subjectCnt = 3; // 과목의 수 // 생성자 public Sungjuk(int hakbun, String name,int kor, int eng, int math) { this.hakbun = hakbun; this.name = name; this.kor = kor; this.eng = eng; this.math = math; this.tot = this.kor + this.eng + this.math; // 총점 계산 this.avg = this.tot / subjectCnt; // 평균 계산 } // 총점과 평균을 구하는 함수 public void CalTotAndAvg() { this.CalTot(); this.CalAvg(); } // 총점을 구하는 함수 private void CalTot() {this.tot = kor + eng + math;} // 평균을 구하는 함수 private void CalAvg() {this.avg = (double)(this.tot) / subjectCnt;} // 국어 점수 Set public void SetKor(int kor) { this.kor = kor; this.CalTotAndAvg(); } // 영어 점수 Set public void SetEng(int eng) { this.eng = eng; this.CalTotAndAvg(); } // 수학 점수 Set public void SetMath(int math) { this.math = math; this.CalTotAndAvg(); } public void SetName(String name) {this.name = name;} public void SetHakbun(int hakbun) {this.hakbun = hakbun;} public int GetHakbun() {return this.hakbun;} public String GetName() {return this.name;} // 과목 점수 출력 public void ShowSubjectInfo() { System.out.println("국어 점수 : " +this.kor); System.out.println("영어 점수 : " +this.eng); System.out.println("수학 점수 : " +this.math); } // 총점과 평균 출력 public void ShowTotAndAvg() { System.out.println("총점 : " +this.tot); System.out.println("평균 : " +this.avg); } // 모든 정보 출력 public void ShowAllInfo() { this.ShowSubjectInfo(); this.ShowTotAndAvg(); } // 학생부 기록과 같이 모든 정보를 출력하는 함수 public void ShowAllInfoRow() { System.out.printf("%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n", this.hakbun, this.name,kor,eng,math,tot,avg); } } public class SungjukTest { public static void main(String[] args) { Sungjuk s1 = new Sungjuk(1,"lee",50,50,50); Sungjuk s2 = new Sungjuk(2,"ha",60,60,60); s1.SetMath(100); s1.ShowAllInfo(); s2.ShowAllInfo(); } }
번외편으로 갑자기 생각난 예제인데, 위의 클래스는 성적에 대한 클래스였다.
그러면 이 성적들이 모이면 학급이 되지 않을까?
즉, 5개의 성적을 배열에 저장해서 출력하는 부분도 만들어보자.
메인 함수만 보면 된다.
프로그램 실행결과
소스 코드
더보기class Sungjuk { private int hakbun; // 학번 private String name; // 이름 private int kor, eng, math; // 과목 점수 private int tot; // 총점 private double avg; // 평균 public static final int subjectCnt = 3; // 과목의 수 // 생성자 public Sungjuk(int hakbun, String name,int kor, int eng, int math) { this.hakbun = hakbun; this.name = name; this.kor = kor; this.eng = eng; this.math = math; this.tot = this.kor + this.eng + this.math; // 총점 계산 this.avg = this.tot / subjectCnt; // 평균 계산 } // 총점과 평균을 구하는 함수 public void CalTotAndAvg() { this.CalTot(); this.CalAvg(); } // 총점을 구하는 함수 private void CalTot() {this.tot = kor + eng + math;} // 평균을 구하는 함수 private void CalAvg() {this.avg = (double)(this.tot) / subjectCnt;} // 국어 점수 Set public void SetKor(int kor) { this.kor = kor; this.CalTotAndAvg(); } // 영어 점수 Set public void SetEng(int eng) { this.eng = eng; this.CalTotAndAvg(); } // 수학 점수 Set public void SetMath(int math) { this.math = math; this.CalTotAndAvg(); } public void SetName(String name) {this.name = name;} public void SetHakbun(int hakbun) {this.hakbun = hakbun;} public int GetHakbun() {return this.hakbun;} public String GetName() {return this.name;} // 과목 점수 출력 public void ShowSubjectInfo() { System.out.println("국어 점수 : " +this.kor); System.out.println("영어 점수 : " +this.eng); System.out.println("수학 점수 : " +this.math); } // 총점과 평균 출력 public void ShowTotAndAvg() { System.out.println("총점 : " +this.tot); System.out.println("평균 : " +this.avg); } // 모든 정보 출력 public void ShowAllInfo() { this.ShowSubjectInfo(); this.ShowTotAndAvg(); } // 학생부 기록과 같이 모든 정보를 출력하는 함수 public void ShowAllInfoRow() { System.out.printf("%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n", this.hakbun, this.name,kor,eng,math,tot,avg); } } public class SungjukTest { public static void main(String[] args) { Sungjuk[] class1 = new Sungjuk[5]; class1[0] = new Sungjuk(1,"lee",50,50,50); class1[1] = new Sungjuk(2,"ha",60,60,60); class1[2] = new Sungjuk(3,"ji",70,70,70); class1[3] = new Sungjuk(4,"park",80,80,80); class1[4] = new Sungjuk(5,"kim",90,90,90); System.out.println("과목의 수 : " +Sungjuk.subjectCnt); System.out.println("-------------------------------------------------------"); System.out.println("학번\t이름\t국어\t영어\t수학\t합계\t평균"); for (int i = 0; i < class1.length; i++) class1[i].ShowAllInfoRow(); System.out.println("-------------------------------------------------------"); } }