메서드 Overloading과 매개변수 - accidentlywoo/java GitHub Wiki

메서드 Overloading과 매개변수


  1. 메서드 Overloading과 생성자 Overloading의 개념 및 필요성을 이해하고 설명할 수 있다.
  2. 매개변수 유형에 따른 메서드의 동작 방식을 이해하고, 가변적 매개변수의 개념을 설명할 수 있다.

메서드 Overloading

변수의 중복 선언

변수와 달리 하나의 클래스에 동일한 이름의 메서드는 여러 개 정의할 수 있음 데이터 타입이 달라도 변수 이름이 동일한경우를 허용하지 않음

클래스 안에 동일한 이름의 변수를 사용했을 때, 프로그램이 모호해지기 때문

public class Employee {
  String name;
  int age;
  char grade;
  String grade;
}

--컴파일 과정에서 에러 발생--> grade 변수는 이미 선언되었기 때문에 동일한 이름의 grade 변수의 선언을 허용하지 않음 데이터 타입이 달라도 변수명이 동일하여 에러가 발생함

메서드의 중복 정의

변수와 달리 하나의 클래스에 동일한 이름의 메서드는 여러 개 정의할 수 있음

매개변수의 개수와 타입을 통해 실행될 메서드를 구분할 수 있기 때문

하나의 클래스에 동일한 이름의 메서드가 여러 개 중복되어 정의되는 것 -> 메서드 Overloading

메서드 Overloading 개념

자바 같은 객체지향 언어에서만 제공되는 독특한 문법 한 클래스 내에서 동일한 이름의 메서드라도 매개변수의 개수와 타입만 다르다면 다른 메서드로 인식하는 것을 의미함 -> 동일한 이름의 메서드라도 매개변수의 형태에 따라 다른 일을 수행할 수도 있음

메서드 Overloading이 필요한 이유는 무엇일까?

public void printInt(int data){}

public void printDoublr(double data){}

public void printChar(char data){}

public void printString(String data){}

모든 데이터 타입별로 printXXX() 메서드를 각각 정의한다면?

  1. 많은 출력 기능의 메서드가 필요하며, 코드의 재사용에도 문제가 발생함 메서드는 화면에 매개변수로 받은 값을 출력하는 공통된 로직들이 반복적으로 작성되어 코드의 재사용을 어렵게 함
  2. 메서드를 호출하는 코드에서 많은 수정이 발생함

정수값을 출력하기 위해 printInt(35); 호출 --프로그램 변경--> 실수 값을 출력하기 위해 printDouble(45.56)

메서드 Overloading으로 문제해결

메서드 Overloading 유형

  1. 매개변수의 개수와 타입이 모두 다른 경우 -> 당근 됨

  2. 리턴 타입이 다른 경우 -> 메서드 Overloading에서 리턴 타입을 무시되므로, 이 소스코드는 Overloading이 아닌 오류

  3. 매개변수의 이름이 다른 경우 -> 메서드의 매개변수 이름이 다른 것은 의미가 없으므로, Overloading이 아닌 오류

  4. 매개변수의 개수와 타입이 같지만 순서가 다른 경우 -> 매개변수의 개수와 타입이 같아도 순서가 다른 것은 Overloading으로 인식함.

  5. 매개변수가 형변환된 다른 타입인 경우

class Overloading {
  void calc(double d) {
     sysout(d+d);
  }
}

public class Test {
  main{
     Overloading o1 = new Overloading();
     o1.calc(30.5);
     o1.calc(45);//int는 double로 묵시적 형변환이 가능하기 떄문에 오류없음
  }
}

생성자 Overloading 개념

  • 생성자 클래스로부터 객체를 생성할 때 객체의 변수들을 초기화하는 역할을 담당하는 메서드 메소드 Overloading이 지원됨 -> 하나의 클래스는 매개변수의 유형과 개수를 달리해서 여러 개의 생성자를 갖도록 함

자바 생성자 Overloading을 지원하는 이유는 무엇일까?

클래스로부터 객체를 생성할 때, 필요한 변수들만 적절히 초기화하기 위해서

특정 클래스로부터 객체 생성 --Overloading 된 생성자 이용--> 필요한 데이터로만 초기화된 객체들을 사용 가능함

public class Employee {
...
  public Employee(String name, int age) {
     this.name = name;
     this.age = age;
  }
  public Employee(String name, int salary) {
     this.salary= salary;
     this.age = age;
  }
}

매개변수의 개수와 타입이 동일하므로, Overloading이라 볼 수 없음 -> 에러 발생!!! 이런 경우는?

매개변수의 위치를 변경한 생성자 Overloading

public class Employee {
...
  public Employee(String name, int age) {
     this.name = name;
     this.age = age;
  }
  public Employee(int salary, String name) {
     this.salary= salary;
     this.age = age;
  }
}

매개변수의 위치를 변경하면, 이름과 급여를 초기화할 수 있는 생성자 Overloading이 됨

this()의 의미와 사용법

  • this 예약어 생성자나 메서드의 매개변수 이름이 객체 뱐수의 이름과 같은 경우 -> 객체 변수 이름 앞에 this를 사용해서 구별함

  • this() 생성자 같은 클래스 내의 Overloading된 다른 생성자 메서드를 호출할 때 사용함

public class Employee {
	int employeeNo;
	String name;
	int age;
	int salary;
	
	public Employee() {
		this.employeeNo = 0;
		this.name = "Anonymity";
		this.age = 0;
		this.salary = 0;
	}
	
	public Employee(int employeeNo, String name) {
		this.employeeNo = employeeNo;
		this.name = name;
	}
	
	public Employee(int employeeNo, String name, int age) {
		this.employeeNo = employeeNo;
		this.name = name;
		this.age = age;
	}
	
	public Employee(int employeeNo, String name, int age, int salary) {
		this.employeeNo = employeeNo;
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
}

-> 중복 코드가 너무 많음 ->this() 메서드를 사용하자

public Employee() {
		this(0,"Anonymity", 0, 0);
	}
	
	public Employee(int employeeNo, String name) {
		this.employeeNo = employeeNo;
		this.name = name;
	}
	
	public Employee(int employeeNo, String name, int age) {
		this(employeeNo, name);
		this.age = age;
	}
	public Employee(int employeeNo, String name, int age, int salary) {
		this(employeeNo, name, age);
		this.salary = salary;
	}

Employee 클래스의 생성자 -> this()를 이용하여 다른 생성자를 호출하기 때문에 생성된 Employee 객체들은 적절한 값들로 초기화됨

매개변수

메서드를 호출해서 객체 간 메시지가 전달될 때 부가 정보가 필요한 경우에는?

매개변수 형태로 전달됨

메서드 매개변수로 전달되는 데이터가 기본형이냐 참조형이냐에 따라 동작 방식이 달라지게 됨

매개변수의 타입에 따른 특직

  1. 값 복사
int score = 80;
sysout(score);

int copyScore = score; // score변수에 저장된 값을 copyScore변수에 할당함
sysout(copyScore);

다른 위치에 두 개의 변수가 동일한 값을 가지게 됨 특정 변수의 값을 수정해도 다른 변수에는 영향을 미치지 않음

  1. 주소 복사
int[] list = {100, 85, 99};

int[] copyList = list; // copyList 변수에 list 변수에 저장된 주소 값을 할당함

list 주소 [!@de6ced] coptList 주소 [!@de6ced]

특정 변수로 배열의 값을 수정하면, 동일한 객체를 참조하는 다른 변수도 수정된 값을 인식함

기본 데이터 타입 : 값에 의한 호출(Call by Value)

매개변수의 타입이 기본 테이터 타입인 경우에는?

메서드를 호출할 때 넘어가는 실 매개변수(매개변수 값) --메서드 호출--> 호출되는 메서드의 인자(형식 매개변수)에 복사함 --메서드의 인자 값 변동--> 실 매개변수 값은 영향을 받지 않음

참조 데이터 타입 : 주소에 의한 호출

참조형 매개변수는 참조하는 객체의 주소 값이 복사되어 전달됨 같은 객체의 주소를 가지기 때문에 하나의 객체를 구 개의 참조변수가 공유함

매개변수로 객체 넘기기

객체지향 프로그램에서는 객체들이 서로 메시지를 주고받으면서 프로그램이 진행됨

객체가 다른 객체의 메서드를 호출할 때 단순히 메서드 수행에 필요한 값만 넘기고자 하는 경우 -> 매개변수를 기본형으로 선언함

메서드 수행 이후에도 수행 결과를 지속적으로 유지하고자 하는 경우 -> 매개변수를 참조형으로 선언함.

가변적 매개변수 개념

매개변수 개수가 지정되어야만 하는 제한을 극복하기 위해 가변적 매개변수를 제공함

  • 가변적 매개변수 매개변수의 숫자를 컴파일이나 실행 시에 미리 지정하지 않은 방식 하나의 메서드만 정의하여 매개변수의 개수를 가변적으로 사용하는 방식

가변적 매개변수를 이용하여 메서드를 선언하는 방법은?

[modifier] 리턴 타입 메서드명(데이터타입 ... 매개변수이름){
//elipsis -> 매개변수가 가변적이다.
}
int sum(int...i){
// 가변적 인자를 이용한 sum()메서드
}

--정의한 sum()메서드를 호출하여 사용시-->

sum(1,1);
sum(1,2,3);
sum(1,1,1,1,1,);
sum(10,20,30,40,50,60,70,80,90,100);

원하는 개수만큼의 int 데이터를 매개변수로 지정하여 사용하면 됨

개수가 다른 매개변수 호출 --매서드 호출--> 가변적 매개변수를 가진 sum() 메서드 호출 ->매개변수 개수에 따른 처리를 담당함

가변적 매개변수 활용

가변적 매개변수로 선언된 메서드는 해당 타입으로 지정된 변수의 배열로 값을 받음

public class VariableArgumentTest {
  public static int intSum(int... num){
     int sum = 0;
     for(int i = 0; i < num.length; i++){
       sum = sum + num[i];
     }
     return sum;
  }
  public static void main~{
   sysout(intSum(1));
   sysout(intSum(1, 2));
   sysout(intSum(1, 2, 3));
  }
}

가변적 매개변수는 여러 개의 매개변수와 같이 사용 가능함

여러 개의 매개변수와 같이 사용할 때 가변적 매개변수의 위치는? -> 매서드 선언부의 매개변수 리스트 마지막 위치에서 딱 한 번만 사용 가능