생성자 필요
객체를 생성하는 시점에 어떤 작업을 하고 싶다면 생성자를 이용
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;
}
}
public class MethodInitMain {
public static void main(String[] args) {
MemberInit memberInit = new MemberInit();
memberInit.name = "user1";
memberInit.age = 15;
memberInit.grade = 90;
MemberInit memberInit1 = new MemberInit();
memberInit1.name = "user2";
memberInit1.age = 15;
memberInit1.grade = 90;
MemberInit[] members = {memberInit, memberInit1};
for (MemberInit member : members) {
System.out.println(member.name + member.age + member.grade);
}
}
}
회원의 초기값을 설정하는 부분 반복 -> 제거
public class MethodInitMain2 {
public static void main(String[] args) {
MemberInit memberInit = new MemberInit();
initMember(memberInit, "userA", 15, 90);
MemberInit memberInit1 = new MemberInit();
initMember(memberInit1, "userB", 15, 80);
MemberInit[] members = {memberInit, memberInit1};
for (MemberInit member : members) {
System.out.println(member.name + member.age + member.grade);
}
}
static void initMember(MemberInit memberInit, String name, int age, int grade){
memberInit.name = name;
memberInit.age = age;
memberInit.grade = grade;
}
}
initMember를 통해서 반복을 제거, 그런데 이 메서드 대부분 MemberInit 객체의 멤버 변수를 사용. MemberInit이 자기 자신 데이터를 변경하는 기능을 제공하는 것이 좋다.
This
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;
}
}
public class MethodInitMain3 {
public static void main(String[] args) {
MemberInit memberInit = new MemberInit();
memberInit.initMember("userA", 15, 90);
MemberInit memberInit1 = new MemberInit();
memberInit.initMember("userB", 15, 80);
MemberInit[] members = {memberInit, memberInit1};
for (MemberInit member : members) {
System.out.println(member.name + member.age + member.grade);
}
}
}
this
initMember의 코드를 보면 메서드의 매개변수에 정의한 String name과 Member 변수의 이름이 String name으로 동일 -> 구분????
이 경우 멤버 변수보다 매개변수가 코드 블록의 더 안쪽에 있기 떄문에 매개변수가 우선순위를 갖는다.
this는 인스턴스 자신의 참조값을 갖는다.

매개변수의 이름과 맴버 변수의 이름이 동일한 경우 this를 사용해서 둘 명확히 구분
this는 인스턴스 자신을 가르킨다.
this의 생략
this는 생략 할 수 있다. 이 경우 변수를 찾을 때 가까운 지역변수를 먼저 찾고 없다면, 다음으로 멤버 변수를 찾는다. 이도 없을 경우 ERROR
public class MemberThis {
String nameField;
void initMember(String nameParameter){
this.nameField = nameParameter;
}
}
nameField는 먼저 지역변수에서 같은 이름이 있는지 찾는다. 이경우 없다면 멤버 변수에서 찾는다.
nameParameter의 경우 지역 변수에서 같은 이름이 있는지 찾는다. 이경우 매개변수가 있으므로, 매개변수 사용
this와 코딩 스타일
this를 사용하는 코딩 스타일이 있고, 아닌 경우도 있다.
생성자 도입
프로그래밍을 하다보면 객체를 생성하고 이후에 바로 초기값을 할당하는 경우가 있다.
따라서 메서드를 매번 만들어야 한다,
대부분의 객체지향언어는 객체를 생성하자마자 즉시 필요한 기능을 좀더 편리하게 수행할 수 있도록 생성자라는 기능을 제공
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;
}
MemberConstruct(String name, int age){
this(name, age, 50);
}
}
생성자는 메서드와 비슷하지만 다음과 같은 차이 있디
1. 생성자의 이름은 클래스 이름과 동일, 따라서 첫 글자도 대문자
2. 생성자는 반환 타입이 없다. 비워둬야 함
3. 나머지는 메서드와 같다.
public class MemberConstructor {
public static void main(String[] args) {
MemberConstruct construct = new MemberConstruct("userA", 15, 80);
MemberConstruct construct1 = new MemberConstruct("userB", 16, 90);
MemberConstruct[] memberConstructs = {construct, construct1};
for (MemberConstruct memberConstruct : memberConstructs) {
System.out.println(memberConstruct.name + memberConstruct.age + memberConstruct.grade);
}
}
}
생성자 호출
생성자는 인스턴스를 생성하고 나서 즉시 호출, 생성자를 호출하는 방법은 new 명령어 다음에 생성자 이름과 매개변수에 맞춰 인수를 전달
new 생성자이름(생성자에 맞는 인수 목록)
new 클래스이름(생성자에 맞는 인수 목록)
이렇게 하면 인스턴스를 생성하고 즉시 해당 생성자를 호출,
생성자 장점
중복 호출 제거
제약
필요한 메서드를 호출하지 않았을 경우 프로그램은 작동은 한다. 하지만 아무런 데이터가 없는 객체가 돌아다니는 것
생성자의 진짜 장점은 객체를 생성할때 직접 정의한 생성자가 있다면, 직접 젖의한 생성자를 반드시 호출. 참고로 생성자 메서드 오버로딩 처럼 여러개 정의, 이 경우 하나만 호출
MemberConstruct(String name, int age, int grade) {...}
호출 하지 않는다면, compileError 발생
기본 생성자
public class MemberInit {
String name;
int age;
int grade;
}
public class MethodInitMain1 {
public static void main(String[] args) {
MemberInit member1 = new MemberInit();
}
}
여기서 new MemberInit()이 부분은 매개변수가 없는 다음과 같은 생성자가 필요
public class MemberInit {
String name;
int age;
int grade;
MemberInit() { //생성자 필요
}
}
기본생성자
매개변수가 없는 생성자를 기본생성자
클래스에 생성자가 하나도 없으면 자바 컴파일러는 매개변수가 없고, 작동하는 코드가 없는 기본 생성자를 자동으로 생성
생성자 하나라도 있다면, 자바는 기본생성자를 형성 X
public class MemberDefault {
String name;
public MemberDefault(){
System.out.println("기본 생성자 호출");
}
}
public class MemberDefaultMain {
public static void main(String[] args) {
MemberDefault memberDefault = new MemberDefault();
System.out.println(memberDefault);
}
}
기본 생성자를 왜 자동으로 생성??
만약 자바에서 기본생성자를 형성X -> 생성자 기능이 필요하지 않은 경우에도 모든 클레스에 개발자가 직접 기본생성자를 정의
정리
생성자는 반드시 호출
생성자가 없다면 기본 생성자가 제공
생성자 하나라도 있다면, 기본 생성자가 제공되지 않는다.
생성자 오버로딩과 this()
public class MemberConstruct {
String name;
int age;
int grade;
//추가
MemberConstruct(String name, int age) {
this.name = name;
this.age = age;
this.grade = 50;
}
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;
}
}
생성자를 하나 추가해서 생성자 2개
새로 추가한 생성자는 grade를 받지 않는다. 대신 grade는 50점
public class ConstructMain2 {
public static void main(String[] args) {
MemberConstruct member1 = new MemberConstruct("user1", 15, 90);
MemberConstruct member2 = new MemberConstruct("user2", 16);
MemberConstruct[] members = {member1, member2};
for (MemberConstruct s : members) {
System.out.println("이름:" + s.name + " 나이:" + s.age + " 성적:" +
s.grade);
}
}
}
this()
두 생성자를 비교해보면 코드 중복
this 라는 기능을 사용하면 생성자 내부에서 자신의 생성자를 호출, this는 인스턴스 자신의 참조값을 가르킨다.
public class MemberConstruct {
String name;
int age;
int grade;
MemberConstruct(String name, int age) {
this(name, age, 50); //변경
}
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()의 규칙
생성자 코드의 첫 줄만 작성 가능
문제풀이
1.
public class Book {
String title;
String author;
int page;
Book(){
this(" ", " ", 0);
}
public Book(String title, String author, int page) {
this.title = title;
this.author = author;
this.page = page;
}
void displayInfo(){
System.out.println("제목 : " + title + "저자 : " + author + " page : " + page);
}
}
public class BookMain {
public static void main(String[] args) {
Book book = new Book("Java", "Seo", 700);
Book book2 = new Book("JPA", "kim", 700);
book.displayInfo();
book2.displayInfo();
}
}