컴퓨터는 잘못이 없다..

[JAVA]생성자란?(DTO만들기,접근지정자,getter,setter메소드,this) 본문

공부/JAVA

[JAVA]생성자란?(DTO만들기,접근지정자,getter,setter메소드,this)

도토리까꿍v 2020. 11. 28. 18:49
Contents 접기

[예제코드]

 

Member.java (Member클래스)

package test.mypac;

public class Member {
	
	public int num; 
	public String name;
	public String addr;	
	
	public void showInfo() {
		//this : 자기자신의 참조값을 의미한다.
		//this.num과 this.name, this.addr로 자기자신 객체의 필드에 접근할 수 있다.
		System.out.println("----정보----");
		System.out.println("번호 :" + this.num);
		System.out.println("이름 : " +this.name);
		System.out.println("주소 :" +this.addr);
		System.out.println("------------");
	}
	
}

 

MainClass05.java

package test.main;
import test.mypac.Member;
public class MainClass05 {
	public static void main(String[] args) {
		/*
		두명의 회원정보를 2개의 Member 객체를 생성해서 담아보세요.
		*/
		
		Member mem1=new Member();
		//아래의 코드를 수행하기 전까진 이 객체의 필드에는 0, null, null이 들어간다.
		mem1.num=1;
		mem1.name="김재성";
		mem1.addr="연남동";
		
		Member mem2 = new Member();
		mem1.num=2;
		mem1.name="김구라";
		mem1.addr="노량진";
		
		
		//필드에 직접 접근하여 필드값 출력해보기
		//mem1객체의 필드
		System.out.println("----정보----");
		System.out.println("번호 :" + mem1.num);
		System.out.println("이름 : " +mem1.name);
		System.out.println("주소 :" +mem1.addr);
		System.out.println("------------");
		
		//mem2객체의 필드 
		System.out.println("----정보----");
		System.out.println("번호 :" + mem2.num);
		System.out.println("이름 : " +mem2.name);
		System.out.println("주소 :" +mem2.addr);
		System.out.println("------------");
		
		//메소드를 사용해보기
		mem1.showInfo();
		mem2.showInfo();
		
		

	}
}

 

[실행결과]

----정보----
번호 :1
이름 : 김재성
주소 :연남동
------------
----정보----
번호 :2
이름 : 김구라
주소 :노량진
------------
----정보----
번호 :1
이름 : 김재성
주소 :연남동
------------
----정보----
번호 :2
이름 : 김구라
주소 :노량진
------------

 

[코드설명]

1. 클래스에서 this는 자기자신의 참조값을 나타낸다.

 

2. 클래스에 필드값을 출력해주는 기능을 넣어 구현할 수 있다.

showInfo()함수 

 

 

[생성자,getter,setter 예제코드]

위 코드에서 필드에 값을 대입하는 방법으로

이렇게 써왔다. 너무 귀찮지 않은가? 생성자 또는 getter, setter메소드를 통해 필드에 값을 넣어보도록 해보자!

또 MemberDTO형식에 대해 알아보자.

 

MemberDTO.java (MemberDTO클래스)

package test.mypac;

public class MemberDTO {

	private int num;
	private String name;
	private String addr;
	
	//생성자(Constructor)
	//객체를 new 할 때 호출되는 생성자
	//생성자 특징은 리턴 type (no return type)가 없고 클래스명과 동일하게 작성해야 한다.
	public MemberDTO(int num, String name, String addr) {
		System.out.println("MemberDto()생성자가 호출됨!");
		 //this.num, this.name, this.addr에 아무것도 없음 0nullnull이 출려될것임
		System.out.println(this.num+this.name+this.addr);
		//매개변수를 통해 this.num, this.name, this.addr에 값을 넣어줌
		//(생상자로 전달받은 값을 필드에 저장한다.)
		this.num = num; 
		this.name = name;
		this.addr = addr;
		System.out.println(this.num+this.name+this.addr);//매개변수로 입력한 값들이 출력될것임 
	}
	
	//기본(default) 생성자를 명시적으로 정의하기
	//생성자는 얼마든지 다중 정의할 수 있다.
	//다중 정의를 overloading 이라고 한다.
	public MemberDTO() {
		// MemberDTO(int num, String name, String addr) 이런 메소드만 있다면 
		//객체 생성 시 MemberDTO dto1 = new MemberDTO(1,"김재성","노량진") 으로만 생성해야 한다.
		//그냥 MemberDTO dto1 = new MemberDTO() 로만 생성하고 나중에 값을 넣고싶다면
		//지금처럼 매개변수가 없는 생성자를 하나 적어주어야 한다. 
	}
	
	//필드에 num값을 수정하는 setter 메소드
	public void setNum(int num) {
		this.num=num;
	}
	
	//필드에 num값을 리턴해주는 getter메소드
	public int getNum() {
		return this.num;
	}
	
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public void setAddr(String addr) {
		this.addr = addr;
	}
	
	public String getAddr() {
		return addr;
	}

	
	
	
}

 

MainClass06.java

package test.main;

import test.mypac.MemberDTO;

public class MainClass06 {
	public static void main(String[] args) {
		
		//MemberDTO 객체 생성해서 참조값을 dto1이라는 이름의 지역변수에 담기
		//new MemberDTO(~)가 의미하는 바! 
		//1.참조값을 의미 2.생성자를 호출해준다.(생성자가 없으면 defalut 생성자를 호출해준다.)
		MemberDTO dto1 = new MemberDTO(1,"김구라","연남동");
		MemberDTO dto2 = new MemberDTO(2,"해골","행신동");
		
		
		//getter, setter메소드 사용하기 
		//num이 DTO클래스에서 private num으로 선언되어있다.
		//dto1.num으로 접근하지 못한다.
		//dto1.num=3 //오류남
		//dto1.num; //오류남
		//따라서 num값에 대입하거나,num값을 불러오고 싶을 때는
		//getter, setter 메소드를 사용한다.
		dto1.setNum(3); //num값에 대입하기
		System.out.println(dto1.getNum()); //num값을 불러서 출력해보기
		
		//디포트 생성자가 있기 때문에 이런식으로도 객체 생성이 가능하다.
		MemberDTO dto3 = new MemberDTO();
		dto3.setNum(1);
		dto3.setName("김구라");
		dto3.setAddr("신사동");
		
	}
}

 

[실행결과]

MemberDto()생성자가 호출됨!
0nullnull
1김구라연남동
MemberDto()생성자가 호출됨!
0nullnull
2해골행신동
3

 

[코드 설명]

 

0.필드의 접근지정자를 private으로 설정하면?

객체 생성 후 참조값.필드명 으로는 필드에 접근할 수 없다. 

 

MemberDTO.java

 

MainClass06.java

 

1. 접근지정자 설정, 매개변수가 있는 생성자, 매개변수가 없는 생성자 만들기

-생성자가 없다면 자동으로 생성자를 만들고 객체를 만들면 호출해준다.

단, 매개변수가 있는 생성자를 만들면 default 생성자는 자동으로 만들어지지 않는다.

따라서 객체 생성시 new 클래스명(인자1, 인자2......) 로만 생성이 가능하다.

new 클래스명() 이렇게도 객체 생성을 하고 싶다면

defalut생성자를 명시적으로 적어주어야한다. 

 

-이때 이렇게 여러가지 생성자를 만들어 주는 것을 생성자 다중정의(Constructor Overloading)이라고 한다. 

 

 

-매개변수가 있는 생성자를 호출하여 객체 생성하고, 필드에 값까지 넣어줄 수 있다.

-defalut생성자를 호출하여 객체 생성할 수 있다. (필드에 값 넣는 것은 아래 getter,setter에서 설명)

MainClass06.java

 

 

2. getter, setter 메소드

case1) 매개변수가 있는 생성자를 통해 필드에 값 대입 했는데 private로 선언된 필드 값을 수정하고 싶다면?

case2) 매개변수가 없는 default 생성자를 통해 객체를 생성했는데 private로 선언된 필드에 값을 대입하고 싶다면?

case3) 어떤식으로든 객체 생성 후 private로 선언된 필드에 값을 대입하고 싶다면?

 

--> 이런 3가지의 경우 getter, setter 메소드를 만들어 주어 해결하면 된다.

MemberDTO.java

 

MainClass06.java

 

 

[MemberDTO 만드는 방법]

MemberDTO.java 처럼 설계된 클래스를 DTO(Data Transfer Object)라고 한다. 

1. 필드의 접근 지정자는 private로 지정
2. 기본 생성자와, 필드에 모든 값을 전달 받는 생성자 2개가 있어야 한다.
3. 필드의 접근 메소드 setter, getter 메소드가 형식에 맞게 정의되어 있어야한다.
(set, get + ctrl+space 하거나 해당 클래스내에서 우클릭 Source-Gnerate Getter/Setter로 만들어주면 된다.)


[생성자의 특징]

0. 생성자를 명시해주지 않으면 자동으로 default생성자를 만들어준다. 또한 객체를 new로 생성할 때 호출된다.

★즉, new 클래스명(~)은 생성자 호출을 의미한다.


1. 생성자는 클래스 이름으로 선언한다.
2. no return type 이다. return을 안한다. 
3. 디포트 생성자이든, 매개변수가 있는 생성자이든 뭐든간에 아무 생성자도 없다면
new하는 순간 자동으로 디포트 생성자가 생성된다. 따라서 new 클래스명()으로 객체 생성이 가능하다. 
그러나 매개변수가 있는 생성자를 하나 이상 생성하면 디포트 생성자는 생성되지 않는다. 
즉, new 클래스명()으로는 객체 생성을 하지 못하고 new 클래스명(인자1,~~)로만 객체 생성을 해줘야한다. 
따라서 new 클래스명() 이런식으로도 객체를 생성하고 싶다면 디포트 생성자를 명시적으로 써주어야 한다. 
이처럼 생성자를 여러개 만들어주는 것을 constructor overloading 이라고 한다.


[public과 private 접근지정자]

public : 전체공개, private : 비공개  
private으로 선언해두면 클래스 안에서만 접근할 수 있다. 
private으로 선언해두면 메인메소드에서 객체.필드명~ 으로 접근할 수 없다. 
따라서 메인메소드에서도 객체의 필드에 접근할 수 있게 하기 위해 get, set 함수를 선언해준다.

 

-필드를 비공개로 하는 이유?
필드를 공개로 해놔서 개발자들이 마구잡이로 수정할 수 있어 잘못된 데이터들을 
대입한다면 어플리케이션의 신뢰성이 떨어질 수 있다.
기계의 부품들을 딱딱한 플라스틱으로 가려놔 부품을 못건드려 기계가 고장나지 않게 한것처럼
필드도 가려놓고 어플리케이션이 고장나지 않도록 해주자!

Comments