본문 바로가기
Java/✿object*객체

[ Java ] 💻 생성자와 메서드

by W_W_Woody 2021. 11. 4.

참고링크

출처: https://javacan.tistory.com/entry/37

 

생성자(Constructor)도 메소드인가?

메소드로 이해하기 쉬운 생성자에 대하여 상세하게 살펴본다. 생성자의 기능과 형태 클래스는 초기화를 위하여 생성자(constructor)라는 특별한 코드 블록을 가질 수 있다. 즉, 생성자는 클래스가 n

javacan.tistory.com

메서드(method)


메서드 구조

class A{
	public void make() {
		System.out.println("make 메서드");
	}
}
  • 반환하는 데이터가 있는 경우 (return)
public class MethodMain01{
	public int add(int a, int b){
    	return a + b;
    }
}
  • 반환하는 데이터가 없는 경우 (void)
public class MethodMain01{
	public void print(String str){
    	System.out.println(str)
    }
}
public void work() { //반환이 아니라 누적이라 void사용 (void는 return안씀)
		 money += 1000;
}

void형 : void;비어있다, 출구가 없는 형식

 

메서드 호출

	public static void main(String[] args){
    	//객체 선언 및 생성
        MethodMain01 method = new MethodMain01();
        int result = method.add(5,8); //반환하는 데이터가 있는 메서드 호출
        System.out.println("result = " +result);

객체를 선언 및 생성을 해야 메서드 호출이 가능!

 

인자(파라미터) 전달 방식

  ① 값 호출(Call by value)

기본 자료형의 값을 인자로 전달하는 방식. 값을 복사하여 전달

public class MethodMain01 {
//인자(파라미터)전달 방식 : 값 호출(Call by value)
	public int increase(int n) {
		++n;
		return n;
	}
	public static void main(String[] args) {
		int var1 = 100;
		
		MethodMain01 me = new MethodMain01(); //객체를 생성해야 전달할 수있다.
		int var2 = me.increase(var1);
		System.out.println("var1: "+ var1 + ",var2: "+ var2);
	}
}

 

  ② 참조 호출(Call by reference)

메서드 호출 시 전달하려는 인자를 참조 자료형(객체)을 사용할 경우를 의미. 주소(reference)를 복사하여 전달

public class MethodMain02 {
//인자 전달 방식: 참조 호출(Call by reference)	
	public void increase (int[] n) { //int[]은 배열(객체), n은 인자이면서 배열명
		for(int i=0;i<n.length;i++) {
			n[i]++;//배열의 요소를 1 증가시킴
		}
	}
	public static void main(String[] args) {
		int[] ref1 = {100,200,300}; //배열의 선언 및 생성, 초기화
		MethodMain02 me = new MethodMain02();
		me.increase(ref1);
		for(int i=0;i<ref1.length;i++) {
			System.out.println("ref1["+i+"]:"+ref1[i]);
		}
	}
}

 

  ③ 가변 인자(Variable Arguments)

자료형이 일치할 때 전달하고자 하는 값의 갯수를 다르게 지정할 수 있다.(가변적)

전달되는 데이터는 내부적으로 배열로 인식

public class MethodMain03 {
//인자 전달 방식:Variable Arguments(가변인자)
	public void argTest(int ... n){ //자료형은 바꿀 수 없다
		for(int i=0;i<n.length;i++) {
			System.out.println("n["+i+"]:"+n[i]);
		}
		System.out.println("---------------");	
	}
	public static void main(String[] args) {
		MethodMain03 me = new MethodMain03(); //객체 선언 및 생성
		
		me.argTest();//아무것도 안 넣을 경우에도 컴파일에러 안난다. 
        			//데이터를 넘기지 않아도 배열은 생성된다.
					//그러나 방이 없는 빈 배열 =length는 0
		me.argTest(10);//n에 10이들어가는게아니라 n이 배열을만들고 그안에 10이 들어간거를 가르킨다.
		me.argTest(20,30);//갯수가 늘어난다하더라도 배열로 처리된다 
		me.argTest(40,50,60);//갯수가 늘어난다하더라도 배열로 처리된다 
	}
}

&amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;출력 결과&amp;amp;amp;amp;amp;amp;amp;amp;amp;gt;

 

생성자(constructor)

그래서 왜 생성자를 사용하는데?


객체를 생성하기 위해서 사용한다! (출입문 역할)

생성자는 객체가 생성될 때 자동적으로 단 한번만 호출되어 필드의 초기화 또는 객체 생성시 반드시 호출되어야 하는 메소드를 호출하는 역할을 한다

생성자는 클래스가 new 표현식에 의해 인스턴스화되어 객체를 생성할 때 객체의 레퍼런스를 생성하기 전에

객체의 초기화를 위해 사용되는 코드의 블록이다.

 

클래스는 초기화를 위하여 생성자(constructor)라는 특별한 코드 블록을 가질 수 있다.

따라서, 생성자는 Java 클래스의 멤버가 아니며, 멤버가 아니므로 상속되지 않는다.

따라서, 오버라이딩의 대상이 될 수도 없다. 또한, 일반적인 메소드 호출방법으로 호출할 수 없다.

 

생성자들은  new 표현식을 통하여 객체의 생성과 함께 실행된다.

Example ex = new Example();

Child            ch  =  new Child();     
(Child타입) ch  =        Chile객체    //Child객체가 만들어지고, ch변수에 주소가 보관되고,그걸 Child타입이라한다.
자료형

 

객체 지향 프로그래밍을 하면서 아무렇지도 않게 사용해 왔던 생성자가 있다

 ex)  Scanner scanner = new Scanner(System.in);

 

생성자의 구조는 메소드와 비슷하지만 메소드와는 다르다. (객체안에 포함되어 있지 않음)

// 일반적인 생성자의 형태
  public class Example {
     public Example() {
        ...
     }
  }

생성자는 접근 제한 수식어인 public, protected, private 만을 쓸 수 있으며

상속되지 않으므로 abstract 또는 final 수식어를 가질 수 없다. 객체의 생성시에만 호출되므로 static일 수 없다.

생성자명이 반드시 클래스명과 동일해야 하고 

메소드가 아니므로 반환값은 void 조차 허용되지 않으며, 아예 반환값이란 있을 수 없다.

즉 (int/void)return 타입이 없다.

 

ˇ 생성자 오버로딩

기본 생성자 하나만을 명시할 수 있는 것이 아니라 다양한 인자를 전달 받아 가공할 수 있는 생성자를 여러개 만들어서 사용할 수 있다. 메서드 오버로딩처럼 인자의 타입, 갯수, 배치 순서의 다를 경우 다른 생성자로 인식.

public class Hello{
   int age;
   String name;
   
   public Hello(){} //기본생성자

   public Hello(int a){
       age = a;
   }
   
   public Hello(String n){
       name = n
   }   
   
   public static void main(String[] args){
        Hello h = new Hello();
        Hello h2 = new Hello(35);
        Hello h3 = new Hello("홍길동");
   }
}

 

생성자 생성 시

public Example() {} (기본생성자) 는 생략이 가능하다.  그러나

main 메서드에서 객체를 생성할 때

인자가 없는 객체를 생성하면 오류가 나기 때문에

 

인자가 있는 객체를 생성하거나,

인자가 없는 객체 생성을 사용할꺼면 기본 생성자를 표시해줘야 한다.

class Car2{
	String color;
	String gearType;
	
	//생성자 오버로딩
	public Car2() {} //★ 기본생성자. 생략이 가능하지만 
    			//생략한다면 Car2 c2 = new Car2();(디폴트생성자) 사용이 불가
	
	public Car2(String c, String g) {
		//생성자 블럭안에는 수행문을 넣을 수있다
		color = c;
		gearType = g;
	}
}
public class CarMain02 {
	public static void main(String[] args) {
		Car2 c2 = new Car2(); //디폴트 생성자
        				//기본 생성자(인자가 없는 생성자)있어야 사용가능
		System.out.println(c2.color+","+c2.gearType+");
		
		Car2 c22 = new Car2("blue","auto");
		System.out.println(c22.color+","+c22.gearType+");
	}
}

 

ˇ this와 this()

this() 에서의 this는 생성자를 의미한다.

단독으로 this쓰는 경우를 알기 전에 먼저 멤버변수와 지역변수의 차이를 알아보자.

 

멤버변수클래스영역에 만들어진다.
: 객체 생성을 해서 메모리에 딸려 올라간다.


지역변수는 클래스 블럭을 제외하고 메서드,생성자,제어문 블럭 내에서 생성된 변수
: 해당 블럭이 종료되면 변수는 소멸한다.

public class LocalVariable { // {로 클래스 영역 시작
//멤버변수는 클래스영역에 만들어진다.
	int b = 200; //멤버 변수: 객체 생성을 해서 메모리에 딸려 올라간다.
	
	public void make() {
	//지역변수 : 클래스 블럭을 제외하고 메서드,생성자,제어문 블럭 내에서 생성된 변수
	//해당 블럭이 종료되면 변수는 소멸한다.
		int a = 100;
		System.out.println("a :"+ a );
		System.out.println("b :"+ b );
	}
	public void fun() {
//		fun 메서드 블럭안에 a변수가 정의되지 않아서 호출 불가
//		System.out.println("a: "+ a); //a소멸되어 호출 불가능
		System.out.println("b: "+ b); //b는 멤버변수 이기 떄문에 호출가능
	}

 

(1) this

객체 내부에서 객체 자신을 칭하고 싶을 때

지역변수와 멤버변수를 구별해야 할 때

이럴 때 사용하는 객체 자신을 가리킬 수 있는 유일한 reference! 이것이 바로 this이다.

 

객체가 만들어지면 객체를 참조하기위해서 보이지않는 주소가 생성된다

참조값을 가지고 있기에 객체내부에서 사용할 수있는 참조변수(객체의 주소가 들어가 있음)의 역할
객체같은 경우에도 이름말고 객체내부에서 객체를 가리킬 때(지칭)

ex)내가 나를 지칭할때 이름써서 3인칭화법 쓰지 않듯이, myself라고 생각할 수 있다.

public class ThisMain {
	public ThisMain() {//생성자
		System.out.println("객체 생성: "+this);
	}	
	public static void main(String[] args) {
		ThisMain tt = new ThisMain(); //tt :참조변수 (객체의 주소가 들어가있다)
		System.out.println("객체 생성 후 : "+ tt); 
	}
}

&amp;lt;출력 결과&amp;gt;

참조 변수에 주소가 저장되는건 맞지만 출력되는건 참조값이다.

출력 결과에 '@숫자 = 유니크한숫자 = (16진수)해시값' 은
같은 객체인지 다른객체인지만 비교, 참조만 하는 용도이다.

 

멤버변수명 지역변수명이 같으면 아래와 같은 상황이 생기므로 this 사용한다.

class ThisTest{
	//은닉화
	private int a;
	//캡슐화
	public void setA(int a) { 
//							int a는 지역변수로 블럭이 끝나면 소멸된다.
//							멤버변수명 지역변수명이 같으면 
//		a = a; 
//							같은 블럭안에있는 같은 명칭이므로 셋다 지역변수로 인식이된다
//		a = n;
//							그럼 int a를 n으로 바꾸고 a=n;하면 해결될 수 있지만
//							java에서 캡슐화 시 인수는 멤버변수의 변수명과 동일시킨다
//							(명칭을 통해서 은닉화를 예상할 수 있게끔 동일명칭을 준다.)
//							멤버변수명과 지역변수명으로 동일하게 명시했기 때문에
//							멤버변수와 지역변수를 구분하기 위해 this를 사용함
		this.a = a; //this.a는 멤버변수 
		
	}
	public int getA() {
		return a;
	}
}
public class ThisMain02 {
	public static void main(String[] args) {
		ThisTest tt = new ThisTest();
		tt.setA(200);
		System.out.println(tt.getA());
	}
}

💻 캡슐화

public class Hello{
    private int a;

    public int getA(){
         return a; 
    }
    public void setA(int a){
         this.a = a;
   }
}

this.멤버변수 를 많이 쓰임 this.멤버메서드는 구별이 안가는 경우가 별로 없어서 잘안씀

 

(2) this() 

현재 객체의 생성자를 의미하는 것이다.

주의 해야 할 점은 생성자의 첫 행에 정의해야 한다는 것이며 그렇지 않으면 Compile시 오류가 발생한다.

다시 말하면 이 this()를 이용하여 한 클래스내의 특정 생성자에서 Overloading되어 있는 다른 생성자를 호출할 수 있는 것이다.

그렇게 함으로 해서 생성자에서 코딩 내용이 중복되는 부분을 막을 수 있다. 

 

this메서드로 정의 해야 함을 알 수 있다.

this()전에 일반 수행자가 있으면 에러가난다.

this()는 생성자 내에서 또다른 생성자를 호출하는 초기화 작업이므로

this메소드를 수행 하고  그다음 수행문을 실행한다.

일반 수행자가 먼저 있을 경우&amp;amp;amp;nbsp;
this 생성자가 먼저 있을 경우

 

예제

 

 

 

 

2021.11.08 - [Java/object*객체] - super()

super( )

상속상황에서

  • 자식클래스의 모든 생성자에 부모 클래스의 기본 생성자를 호출하는 super()가 생략되어 있음
  • 매개변수 미입력 또는 super() 생략시, 부모 클래스 기본 생성자 호출
  • 매개변수 입력시, 그에 맞는 부모 클래스 생성자 호출

'Java > ✿object*객체' 카테고리의 다른 글

[Java] 💻String과 StringBuffer,StringBuilder  (0) 2021.11.09
[ Java ] 💻 캡슐화  (0) 2021.11.04
[Java] 💻접근제한자  (0) 2021.11.04

댓글