본문 바로가기
국비 교육/백엔드(Java, Spring)

[자바] 오버로딩(Overloading), 생성자(Constuctor)

by 육츠 2024. 1. 23.
Contents 접기

메소드 오버로딩

한 클래스 내에 같은 이름의 메소드를 여러 개 정의하는 것을 말함.

조건
- 메소드의 이름이 동일해야한다.
- 매개변수의 개수 또는 데이터 타입이 달라야 한다.

 

public static int add 가 같으면 오버로딩이다. 호출하는 곳에서만 알면 된다.

public class OverloadingTest01 {

	public static void main(String[] args) {
		
		add(1, 2); //1
		add(2, 3, 4); //2
		add(1.0,  2.0); // 3
		add(2.0, 3.0, 4.0); // 4
		
		add(1.5F,1.6F); // F: float 타입 
		// 3 : 프로모션이 가능한 것이 호출된다.
		
		int result = add('a', 'b'); // 1
		System.out.println(result); // 195 출력
		
	}
	
	// public static int add 가 같으면 오버로딩
	// 호출하는 곳에서만 알면 된다.
	
	public static int add(int x, int y) {
		return x + y;
	} // 1
	
	public static int add(int x, int y, int z) {
		return x + y + z;
	} // 2 : 매개변수 개수가 다름
	
	public static double add(double x, double y) {
		return x + y;
	} // 3 : 타입이 다름
	
	public static double add(double x, double y, double z) {
		return x + y + z;
	} // 4
	

}
코드 의미
add(1.5F,1.6F);  3 : 프로모션이 가능한 것이 호출된다.
F: float 타입 
int result = add('a', 'b');  1 : 프로모션이 가능한 것이 호출된다.
195 출력 (int 'a' = 97)

 

가변 인자 메소드

전달할 인수의 개수가 정확하지 않은 경우 가변인자를 사용하여 메소드를 정의할 수 있다. (인자의 개수에 상관없이)
메소드 안에서 배열 처럼 사용하며 같은 타입이어야 한다.

하지만 배열처럼 나온다고 해서 데이터를 배열의 형태로 값을 받으면 안된다. 배열처럼 사용하는 것일 뿐 처음 데이터 입력도 배열의 형식으로 받아야 하기 때문이다. ==> 그러면 가변의 의미를 잃게 된다.

public class VariableParamTest {

	public static void main(String[] args) {
		// add(); 
		//  [I@1c655221 : 주소 (인트 배열의 주소와 같다.)
		
		// add(10);
		 // add(10, 20);
		 
		 
	}
	
	public static int add(int...x) {// 파라미터에서만 가능하다
		// System.out.println(x);
		// System.out.println(x[0]);
		//System.out.println(x.length);
		System.out.println("두 번째 메소드");
		return 0;
	}
	
	// 가변인자 메소드 보다 타입이 정확한 메소드가 우선순위가 높다.
	public static int add(int x, int y) {
		 System.out.println("첫 번째 메소드");
		return 0;
	}
	
	
}
코드 의미
add();   [I@1c655221 : 주소 (인트 배열의 주소와 같다.)
add(10); System.out.println(x[0]);
= 10
add(10, 20); System.out.println(x.length);
= 2
add(10, 20); public static int add(int...x)  vs public static int add(int x, int y)

가변인자 메소드 보다 정확한 타입의 메소드 우선순위가 높다.

 

생성자

개발자가 생성자를 만들지 않으면 JVM 이 만든다. 
기본 생성자  (파라미터가 전혀 없는)   ==> 호출 예시 :  FriendVO vo = new FriendVO();

기본 생성자

public FriendVO() {	}
코드 의미
public FriendVO() { }

package phone;

public class friendTest {

    public static void main(String[] args) {
        FriendVO friend;
        friend = new FriendVO(); 
        ....
0 , 0.0 , false, null : 기본값으로 초기화 시켜준다.

friend.output(); 
null(0, null) : null 기본값으로 초기화 됨
public FriendVO() {
    this.name = "사오정";
    this.phoneNo = "010-1111-2222";
    this.birthday = "2020. 12. 25";
    this.age = 24;
}
기본값으로 세팅  new 하면 바로 올라가게 된다.
==> 옳지 않은 방법이다.

friend.output(); 
사오정(24, 2020. 12. 25) : 010-1111-2222 

 

생성자 오버로딩

모든 멤버들에 대한 정보를 담아 초기화 시키는 생성자이다.
생성자 오버로딩만 만들면 기본 생성자를 만들지 않기 때문에 오버로딩한 메서드만 만들면 안된다.

	public FriendVO(String name, String phoneNo, String birthday, int age) {
		// super(); : 상속
		this.name = name;
		this.phoneNo = phoneNo;
		this.birthday = birthday;
		this.age = age;
	}

 

필요한 정보 : 이름 , 전화번호, 생년월일, 나이 ==> 추상화

package phone;


public class FriendVO {
	// 이름 , 전화번호, 생년월일, 나이

	private String name;
	private String phoneNo;
	private String birthday;
	private int age;
	
	
	public FriendVO() {	}
    
	// 생성자 오버로딩
	// 모든 멤버들에 대한 정보를 담아 초기화 시키는 생성자
	
	public FriendVO(String name, String phoneNo, String birthday, int age) {
		// super(); : 상속
		this.name = name;
		this.phoneNo = phoneNo;
		this.birthday = birthday;
		this.age = age;
	}
	

	// getter
	public String getName() {
		return name;
	}

	public String getPhoneNo() {
		return this.phoneNo; // this 빼도 됨
	}

	public String getBirthday() {
		return birthday;
	}

	public int getAge() {
		return age;
	}

	// setter
	public void setName(String name) {
		this.name = name;
	}

	public void setPhoneNo(String phoneNo) { // 같은 타입으로 받아야 함
		this.phoneNo = phoneNo;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public void setAge(int age) {
		this.age = age;
	}

	// 출력 메소드
	public void output() {
		System.out.printf("%s(%d, %s) : %s \n", name, age, birthday, phoneNo);
	}

}
package phone;

public class friendTest {

	public static void main(String[] args) {
		FriendVO friend;
		friend = new FriendVO(); 
		// 기본 생성자가 호출됨 출력
		
		friend.output(); 
		// null(0, null) : null 기본값으로 초기화 됨
		
		// 사오정(24, 2020. 12. 25) : 010-1111-2222 
		
		FriendVO friend2 = new FriendVO("홍길동","010-1111-3333","1995.01.01",30); 
		friend2.output();
		
		//setter 는 기존 생성 되어있는 것에 값을 변경하는 용도이기 때문에 쓰임새가 전혀 다르다.
		
	}

}

홍길동(30, 1995.01.01) : 010-1111-3333

Q . 이렇게 값을 넣을 수 있다면 Setter 가 필요 없지 않을까? 
A . setter 는 기존에 생성 되어있는 것에 값을 변경하는 용도이기 때문에 생성자를 통해 데이터를 만드는 것과 쓰임새가 전혀 같지 않다.

 

++ 이 부분은 피트니스 회원 관리 프로젝트에서 사용된다.

static 과 non - static 호출

static 은 먼저  메모리에 올라가 있다.  non-static 은 과연 new 를 하여 메모리에 올렸을까?

그것을 모르기 때문에 static 은 non-static을 호출할 수 없는 것이다. 하지만 non-static이 static을 호출 하는 것은 가능하다.

그 이유는 non-static이 메모리에 이미 올라가있는 static을 호출하게 되는 때는 non-static도 메모리에 올라가져 있을 때이다.
그렇다는 것은 두 메소드가 다 메모리에 올라와져 있기 때문에 호출이 가능한 것이다.

코드 의미
public class FitnessMain {
// 1) Scanner scanner = new Scanner(System.in);
// 2) static Scanner scanner = new Scanner(System.in);
FitnessMain 에서 호출됨으로서
1) create() 와는  우리 멤버.
2) static 을 붙여 미리 메모리에 올려  대기 , main 과 우리멤버

다른 곳에서도 사용할 수 있게 했다.
public static void main(String[] args) { main 에서는 

1) choice = service.scanner.next(); // static 이 non static 을 호출 할 수 없으니 기본 생성자(FitnessMain service = new FitnessMain();) 을 호출하여 사용하였다.
2) choice = scanner.next(); // 우리 멤버
package main;

import java.util.Scanner;

public class FitnessMain {
	// Scanner scanner = new Scanner(System.in); // 여기 있으면서 우리 멤버가 됨
	static Scanner scanner = new Scanner(System.in); // 여기 있으면서 우리 멤버가 됨
	// 다른 곳에서도 사용할 수 있게 
	
	Fitness member; // 기본값(null) 로 초기화되어 있다.
	
	public static void main(String[] args) {

		FitnessMain service = new FitnessMain(); // 기본 생성자

		String choice;

		// 실행할때 마다 보여야 함

		while(true) {
			service.menu(); // main 은 우리 멤버가 아니다.
			// choice = service.scanner.next();
			choice = scanner.next();
		private void create() {
		System.out.println(" [ 회원 등록 ] ");
		
		String id, name; // 지역 변수
		double weight, height;
		
		System.out.print("> 아이디: "); id = scanner.next();
		System.out.print("> 이  름: "); name = scanner.next();
		System.out.print("> 키(cm): "); height = scanner.nextDouble();
		System.out.print("> 몸무게(kg): "); weight = scanner.nextDouble();
		
		member = new Fitness(id, name, height, weight); // 패키지 import 
		// 지역변수
		
		System.out.println("## 회원 등록 완료\n");
		
	}
코드 의미
System.out.print("> 아이디: "); id = scanner.next();
System.out.print("> 이  름: "); name = scanner.next();
System.out.print("> 키(cm): "); height = scanner.nextDouble();
System.out.print("> 몸무게(kg): "); weight = scanner.nextDouble();
main () 에서 먼저 객체를 메모리에 올리기 때문에 non-static 에서 static 을 호출하여 입력 받는게 가능한 것이다.