[Java] 생성자
대부분의 객체 지향 언어는 객체를 생성하자마자 즉시 필요한 기능을 좀 . 더편리하게 수행할 . 수있도록 생성자라는 기능을 제공한다.
생성자를 사용하면 객체를 생성하는 시점에서 즉시 필요한 기능을 수행할 . 수있다.
기존 코드를 유지하기 위해 MemberConst 라는 새로운 클래스를 작성하였다.
package construct;
public class MemberCon {
String name;
int age;
int grede;
Membercon(String name, int age, int grade) {
System.out.println("생성자 호출 =" + name + "age" + age + "grade" + grade);
this.name = name;
this.age = age;
this.grede = grade;
}
}
생성자는 메서드와 비슷하지만,
- 생성자의 이름은 클래스이름과 같다. 따라서 첫 글자도 대문자로 시작한다.
- 생성자는 반환 타입이 없다. 비워놔야한다.
- 나머지는 메서드랑 같다.
package construct;
public class MemberconMain1 {
public static void main(String[] args) {
MemberCon member1 = new MemberCon("user1", 16, 90);
MemberCon member2 = new MemberCon("user2", 20, 50);
MemberCon[] members = {member1, member2};
for (MemberCon s : members) {
System.out.println("생성자 호출 =" + s.name + " age" + s.age + " grade" + s.grede);
}
}
}
() : 괄호를 포함해야하는 이유는 생성자 때문이다. 객체를 생성하면서 동시에 생성자를 호출한다는 의미를 포함한다.
지금까지 new 키워드를 사용하면서 객체를 생성할 때마다 ()을 사용했던 이유는 바로 "생성자" 때문이다.
객체를 생성하면서 동시에 "생성자" 를 호출해야한다는 의미를 포함한다.
그렇다면 생성자의 장점은
- 중복 호출을 제거
메서드를 한번 . 더호출해야 했다. 하지만 생성자를 생성하면 동시에 생성하고 작업을 줄이는 효과가 있다.
생성자 등장 전,
Construct01 member2 = new Construct01();
initMember(member2, "user2", 22, 87);
//static 메서드는 main 메서드 밖에서 정의 해야함
static void initMember(Construct01 member, String name, int age, int grade) {
member.name = name;
member.age = age;
member.grade = grade;
생성자 등장 후,
MemberCon member1 = new MemberCon("user1", 16, 90);
- 제약- 호출 필수
메서드에서 실수로 호출을 빼먹으면 프로그램을 작동한다.
하지만 생성자는 오류가 생긴다.
메서드의 경우
Construct01 member1 = new Construct01();
initMember(member1, "yun", 14, 90);
Construct01 member2 = new Construct01();
//initMember(member2, "user2", 22, 87);
하나를 빠져도 제대로 들어간다.
생성자의 경우
package construct;
public class MemberconMain1 {
public static void main(String[] args) {
// MemberCon member1 = new MemberCon("user1", 16, 90);
MemberCon member2 = new MemberCon("user2", 20, 50);
MemberCon[] members = {member1, member2};
for (MemberCon s : members) {
System.out.println("생성자 호출 =" + s.name + " age" + s.age + " grade" + s.grede);
}
}
}
java: cannot find symbol
symbol: variable member1
location: class construct.MemberconMain1
라는 오류가 생성된다.
package construct;
public class MemberconMain1 {
public static void main(String[] args) {
/MemberCon member1 = new MemberCon(/*"user1", 16, 90*/);
MemberCon member2 = new MemberCon("user2", 20, 50);
MemberCon[] members = {member1, member2};
for (MemberCon s : members) {
System.out.println("생성자 호출 =" + s.name + " age" + s.age + " grade" + s.grede);
}
}
}
의 경우에도 오류가 뜬다.
생성자를 사용하면 필수값 입력을 보장할 수 있다.
생성자는 반드시 호출되어야 한다.
생성자가 없으면 기본 생성자가 제공된다.
생성자가 하나라도 있으면 기본 생성자가 제공되지 않는다. 이런 경우에는 개발자가 직접 호출해야한다.
생성자 - 오버로딩 과 this()
package construct;
public class MemberCon {
String name;
int age;
int grede;
//생성자 추가
MemberCon(String name, int age) {
this.name = name;
this.age = age;
this.grade = 50; //이름과 나이가 있으면 성적은 50점부터 시작한다,
}
MemberCon(String name, int age, int grade) {
System.out.println("생성자 호출 name =" + name + ", age =" + age + ", grade =" + grade);
this.name = name;
this.age = age;
this.grede = grade;
}
}
기존에 있던 생성자와 해서 두개가 생성되었다. 이를 오버로딩이라고 한다.
MemberCon {
String name;
int age;
int grede;
//생성자 추가
MemberCon(String name, int age) {
this.name = name;
this.age = age;
this.grade = 50;
새로 생성된 생성자는 grade 를 안받으나, this grade = 50 을 통해 50점을 받는다.
package construct;
public class MemberconMain2 {
public static void main(String[] args) {
MemberCon member1 = new MemberCon("user1", 16, 90);
MemberCon member2 = new MemberCon("user2", 20);
MemberCon[] members = {member1, member2};
for (MemberCon s : members) {
System.out.println("생성자 호출 =" + s.name + " age" + s.age + " grade" + s.grade);
}
}
}
생성자 호출 name =user1, age =16, grade =90
생성자 호출 =user1 age16 grade90
생성자 호출 =user2 age20 grade50
grade 를 안적을 경우 위의 생성자에서 적용한 50 점이 호출되게 된다.
this()
두 생성자를 비교해 보면 코드가 중복되는 부분이 있다.
package construct;
public class MemberCon {
String name;
int age;
int grade;
//생성자 추가
MemberCon(String name, int age) {
this.name = name;
this.age = age;
this.grade = 50; //이름과 나이가 있으면 성적은 50점부터 시작한다,
}
MemberCon(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.name, this.age, this.grade 부분이 중복이 된다.
이 중복을 제거하기 위해서는
package construct;
public class MemberCon {
String name;
int age;
int grade;
//생성자 추가
MemberCon(String name, int age) {
this(name, age, 50);
}
MemberCon(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(name, age, 50); 처럼 점수 항족 50을 넣고 시작할 한다.
메인에서
MemberConstruct memeber1 = new MemberConstruct("user1", 15, 90);
MemberConstruct memeber2 = new MemberConstruct("user2", 18);
할 경우에
user1 15 90
user2 18 50
로 출력된다.
문제풀이1
//BookMain 코드가 작동하도록 Book 클래스를 완성하세요
//특히 Book클래스의 생성자 코드에 중복이 없도록 주의하시오
package construct;
public class BookMain {
public static void main(String[] args) {
//기존 생성자 사용 Book()가 전용으로 사용할 수 있는 생성자가 필요하다.
Book book1 = new Book();
book1.displayinfo();
//title과 author 만을 매개변수로 받는 생성자
Book book2 = new Book("Hello", "song");
book2.displayinfo();
Book book3 = new Book("Hi", "yun", 10);
book3.displayinfo();
}
}
package construct;
public class Book {
String title;
String author;
int page;
//book() 에 대한 기본 생성자가 필요하다.
//이미 생성자를 사용하고 있기 때문에 () 만 입력해서 나왔던 기본 생성자를 입력해주지 않는다.
Book(){
}
//코드 완성
Book(String title, String author, int page) {
this.title = title;
this.author = author;
this.page = page;
}
Book(String title, String author) {
this.title = title;
this.author = author;
this.page = 0;
}
void displayinfo() {
System.out.println("Title: " + title);
System.out.println("Author: " + author);
}
}
중복을 없게 할려면,
package construct;
public class Book {
String title;
String author;
int page;
//book() 에 대한 기본 생성자가 필요하다.
//이미 생성자를 사용하고 있기 때문에 () 만 입력해서 나왔던 기본 생성자를 입력해주지 않는다.
Book(){
this("","",0);
}
//코드 완성
Book(String title, String author, int page) {
this(title, author);
}
Book(String title, String author) {
this.title = title;
this.author = author;
this.page = 0;
}
void displayinfo() {
System.out.println("Title: " + title);
System.out.println("Author: " + author);
}
}