728x90
반응형
메서드 Method
- 객체의 동작(기능)을 담당하는 요소
- 반드시 호출되어야만 사용 가능(호출당해서 작업을 수행하는 메서드 : Worker 메서드)
- (특정 메서드를 호출하는 메서드 : Caller 메서드)
- 메서드 구현부(바디) 내에서 작업을 수행하는 도중 작업을 중지하고 호출한 곳으로 되돌아가려면 return 문을 사용
- 단, 리턴타입에 따라 return 문 뒤에 데이터를 명시할 수도 있고 return 문 자체를 생략할 수도 있음
- 매개변수는 1개 이상의 변수를 선언할 수 있지만 리턴값은 1개만 리턴 가능(동시에 2개 이상 리턴 불가)
메서드 정의 기본 문법
[제어자] 리턴타입 메서드명([매개변수선언]...) {
// 메서드가 호출되면 실행될 코드들...
[return [값];]
}
제어자 : 생략이 가능하며, 차후에 배움
리턴타입 : 메서드 실행 후 리턴되는 결과값의 데이터타입 (리턴값이 없을 때 특수한 데이터타입인 void 를 사용)
메서드명 : 호출할 때 사용할 이름을 지정. 식별자 작성 규칙 적용
매개변수 : 메서드 호출 시 전달할 데이터를 저장할 변수 선언
- 위의 요소가 포함되는 부분을 메서드 **헤더(선언부)**라고 함
- 매개변수(Parameter, 파라미터)라고 하며 매개변수에 전달할 데이터를 전달인자(Argument, 아규먼트)라고 함
메서드 선언부 뒤의 중괄호{} 에 해당하는 부분은 메서드가 호출되면 실행될 코드들이 기술되는 부분이며 메서드 **바디(구현부)**라고 함
메서드 정의 형태에 따른 분류
- 매개변수도 없고, 리턴값도 없는 메서드
- 매개변수는 없고, 리턴값만 있는 메서드
- 매개변수만 있고, 리턴값은 없는 메서드
- 매개변수도 있고, 리턴값도 있는 메서드
// 1. 매개변수도 없고, 리턴값도 없는 메서드 정의
// => 리턴값이 없으므로, 리턴타입 부분에 특수 자료형인 void 를 명시
// => 매개변수가 없으므로 메서드 선언부 소괄호() 안을 비워둠
public static void sister_1() {
System.out.println("동생 : 오빠가 불 끄라고 시켜서 불을 껐다!");
// 리턴타입이 void 인 메서드에는 return 문을 사용은 가능하나
// return 문 뒤에 아무런 데이터도 지정하지 못함
return; // 현재 메서드 수행을 종료하고 돌아가라는 의미(생략 가능)
}
// 2. 매개변수는 없고, 리턴값만 있는 메서드 정의
// => 리턴값이 있으므로, 리턴값에 해당하는 자료형을 명시
// => 매개변수가 없으므로 메서드 선언부 소괄호() 안을 비워둠
public static String sister_2() {
System.out.println("동생 : 오빠가 물 떠오라고 시켰다!");
String water = "물";
System.out.println("동생 : 오빠에게 물을 떠다 줬다!");
// 리턴값이 있으므로 메서드 작업 종료 부분에 return 을 명시하고
// return 문 뒤에 리턴할 데이터(변수 또는 리터럴)를 명시
return water; // 변수 지정 또는
// return "물"; // 리터럴 지정 가능
// => return 할 데이터타입이 String 이므로 리턴타입에 String 명시
}
// 3. 매개변수만 있고, 리턴값은 없는 메서드 정의
// => 리턴값이 없으므로 리턴타입에 void 명시
// => 메서드 호출 시 정수 1개를 전달하므로 정수를 저장할 매개변수 선언
public static void sister_3(int money) {
// => Caller 로부터 전달받은 정수 데이터를 매개변수 money 에 저장
// (메서드 내에서 int money = X; 형태의 문장과 동일하게 사용됨)
System.out.println("동생 : 오빠가 준 돈 = " + money + "원");
money -= 200;
System.out.println("동생 : 오빠가 준 돈으로 과자를 사먹었다!");
System.out.println("동생 : 남은돈 = " + money + "원");
// 리턴타입이 void 이므로 리턴할 데이터가 없음
// return; 형태로 명시하거나 생략 가능
// return;
}
// 4. 매개변수도 있고, 리턴값도 있는 메서드 정의
// => 리턴값이 있으므로, 리턴타입 부분에 리턴할 데이터타입 명시
// => 매개변수가 있으므로 소괄호() 안에 전달받은 데이터 저장 변수 선언
public static String sister_4(int money) {
// 외부로부터 전달받은 정수 200 이 매개변수 money 에 저장됨
System.out.println("동생 : 오빠가 과자 사오라고 " + money + "원을 줬다!");
money -= 200;
System.out.println("동생 : 새우깡 사고 " + money + "원이 남았다!");
// 리턴타입이 String 이므로 String 타입 데이터가 리턴되어야함!
return "새우깡";
}
// 5. 매개변수가 2개 이상인 메서드
// => 매개변수가 여러개일 때 해당 갯수와 타입 만큼 변수 선언 필요
// 주의사항! 전달된 데이터의 순서대로 선언해야함!
public static String sister_5(String snack, int money) {
// "새우깡", 1000 을 전달했으므로 String, int 순으로 변수 선언 필요
System.out.println("동생 : 오빠가 준 과자 = " + snack);
System.out.println("동생 : 오빠가 준 돈 = " + money + "원");
money -= 1000;
snack = "쿠쿠다스";
return snack;
}
// 1. 매개변수도 없고, 리턴값도 없는 메서드 호출
System.out.println("동생아! 불 좀 꺼라!");
// => sister_1() 메서드는 매개변수가 없으므로
// 메서드 호출 시 소괄화 내부에 아무 데이터도 전달하지 못함
sister_1();
System.out.println("동생이 불을 끄고 갔다!");
System.out.println("=========================================");
// 2. 매개변수는 없고, 리턴값만 있는 메서드 호출
// => sister_1() 메서드는 매개변수가 없으므로
// 메서드 호출 시 소괄호 내부에 아무 데이터도 전달하지 못함
// => 리턴값이 있으므로 변수에 리턴값을 저장하거나
// 출력문 등에 바로 사용할 수도 있음
System.out.println("동생아! 물 좀!");
String result = sister_2(); // 리턴값을 result 변수에 저장
System.out.println("동생이 가져다 준 것 : " + result);
// -----------------------------------------
// 리턴값을 출력문에 바로 사용 가능
System.out.println("동생이 가져다 준 것 : " + sister_2());
// -----------------------------------------
// 주의! 리턴값이 없는 메서드는 변수에 저장 또는 출력문에 사용 불가
// result = sister_1(); // 오류 발생! 리턴타입이 void 이므로 저장 불가
System.out.println("=========================================");
// 3. 매개변수만 있고, 리턴값은 없는 메서드
System.out.println("동생아! 200원 줄테니 과자 사먹어라!");
// => 매개변수가 있으므로 메서드 호출 시점에서 소괄호에 데이터 전달 필요
// (전달할 데이터는 변수 또는 리터럴 사용 가능)
sister_3(200); // 메서드 호출 시 정수 200을 전달
// int money = 200;
// sister_3(money); // 메서드 호출 시 정수형 변수를 전달
// => 메서드 파라미터(매개변수) 부분에 아무것도 전달하지 않으면
// sister_3(); // 오류 발생! 매개변수 타입 및 갯수와 일치해야함
// The method sister_3(int) in the type Ex is not applicable for the arguments ()
System.out.println("=========================================");
// 4. 매개변수도 있고, 리턴값도 있는 메서드
System.out.println("동생아! 200원 줄테니 새우깡 좀 사다 도!");
// sister_4() 메서드 호출 시 매개변수에 전달할 데이터가 필요
String snack = sister_4(500); // 메서드 호출 시 정수 200 전달
// => 메서드 작업 종료 후 문자열이 리턴되므로 변수 snack 에 저장
System.out.println("동생이 사다준 것 : " + snack);
System.out.println("=========================================");
// 5. 매개변수가 2개 이상인 메서드
// => 3번 또는 4번 유형 메서드에서 전달할 데이터가 2개 이상인 경우
// => 각 데이터를 콤마(,)로 구분하여 전달
System.out.println("동생아! 1000원 줄테니 새우깡을 쿠쿠다스로 바꿔온나!");
snack = sister_5("새우깡", 1000); // String, int 순으로 전달
System.out.println("동생이 바꿔다 준 것 : " + snack);
반응형
메서드 오버로딩 Method Overloading = 메서드 다중 정의
- 시그니처(리턴타입, 메서드명, 매개변수 중) 매개변수(파라미터)가 다른 메서드를 여러번 정의하는 것
- 동일한 작업을 수행하는 메서드의 매개변수 타입이 다를 때 메서드 이름을 별도로 구분하지 않고, 같은 이름의 메서드를 매개변수만 달리 하여 여러번 정의하는 것
- 메서드 호출 시점에서 전달되는 데이터 타입에 따라 매개변수 타입이 일치하는 해당 메서드를 자동으로 호출함
- 매개변수 이름만 다르거나, 리턴타입만 다른 것은 오버로딩이 아님
class OverloadingMethod {
// 정수 1개를 전달받아 절대값을 계산하여 출력하는 abs() 메서드 정의
// => int, double, long 타입에 대한 각 메서드를 abs() 이름으로 통일
// 단, 매개변수 타입만 int, double, long 으로 구분
public void abs(int num) {
// 전달받은 정수 num 이 음수일 경우 양수로 변환 후 출력
// 아니면 그대로 출력
if(num < 0) {
num = -num;
}
System.out.println("num = " + num);
}
// 매개변수의 타입이 같고, 변수명만 다른 것은 오버로딩이 아니다!
// public void abs(int num2) {} // 컴파일 에러 발생!
// 매개변수가 같고, 리턴타입만 다른 것은 오버로딩이 아니다!
// public int abs(int num) {} // 컴파일 에러 발생!
// int형이 아닌 다른 타입 매개변수를 선언하면 오버로딩이 성립됨!
public void abs(double num) {
// 전달받은 실수 num 이 음수일 경우 양수로 변환 후 출력
// 아니면 그대로 출력
if(num < 0) {
num = -num;
}
System.out.println("num = " + num);
}
public void abs(long num) {
// 전달받은 long 타입 정수 num 이 음수일 경우 양수로 변환 후 출력
// 아니면 그대로 출력
if(num < 0) {
num = -num;
}
System.out.println("num = " + num);
}
}
class NormalMethod {
// 정수 1개를 전달받아 절대값을 계산하여 출력하는 abs() 메서드 정의
public void abs(int num) {
// 전달받은 정수 num 이 음수일 경우 양수로 변환 후 출력
// 아니면 그대로 출력
if(num < 0) {
num = -num;
}
System.out.println("num = " + num);
}
// double 타입 실수를 전달받는 메서드를 별도로 정의
// => 메서드명도 식별자이므로 중복되면 안된다!
public void dAbs(double num) {
// 전달받은 정수 num 이 음수일 경우 양수로 변환 후 출력
// 아니면 그대로 출력
if(num < 0) {
num = -num;
}
System.out.println("num = " + num);
}
// long 타입 정수를 전달받는 메서드 별도 정의
public void lAbs(long num) {
// 전달받은 정수 num 이 음수일 경우 양수로 변환 후 출력
// 아니면 그대로 출력
if(num < 0) {
num = -num;
}
System.out.println("num = " + num);
}
// 데이터 1개를 전달받아 출력하는 print() 메서드
public void intPrint(int data) {
System.out.println(data);
}
public void StringPrint(String data) {
System.out.println(data);
}
public void doublePrint(double data) {
System.out.println(data);
}
}
NormalMethod nm = new NormalMethod();
nm.abs(-10);
nm.dAbs(-3.3);
nm.lAbs(-30L);
System.out.println("------------------------");
OverloadingMethod om = new OverloadingMethod();
om.abs(-10); // public void abs(int num) {} 메서드가 호출됨
om.abs(-3.3); // public void abs(double num) {} 메서드 호출됨
om.abs(-30L); // public void abs(long num) {} 메서드 호출됨
// => 즉, 메서드 파라미터 전달 시, 매개변수를 구분할 수 있으면
// 메서드 오버로딩이 성립되는 것으로 간주하고 오류 발생 없음!
메서드 오버로딩(매개변수 갯수 또는 순서가 다른 메서드)
- 매개변수의 타입이 같더라도 갯수가 다르면 오버로딩이 성립됨 단, 타입이 같은 매개변수간의 순서 변경은 오버로딩이 아님
class OverloadingMethod {
// 매개변수 갯수가 다른 메서드 오버로딩
// 정수 2개를 전달받는 print() 메서드 정의
public void print(int n1, int n2) {
System.out.println(n1 + ", " + n2);
}
// 정수 3개를 전달받는 print() 메서드 정의
public void print(int n1, int n2, int n3) {
System.out.println(n1 + ", " + n2 + ", " + n3);
}
// ------------------------------------------------------
// 정수 1개(count)와 문자열(name) 2 ~ 4개까지 전달받는
// print2() 메서드 정의
public void print2(int count, String name1, String name2) {
System.out.println(count + " : " + name1 + ", " + name2);
}
public void print2(int count, String name1, String name2, String name3) {
System.out.println(count + " : " +
name1 + ", " + name2 + ", " + name3);
}
public void print2( int count,
String name1, String name2, String name3, String name4) {
System.out.println(count + " : " +
name1 + ", " + name2 + ", " + name3 + ", " + name4);
}
// ------------------------------------------------------
public void sum(int num1, double num2) {
System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
}
public void sum(double num1, int num2) {
System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
}
public void sum(int num1, int num2) {
System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
}
// 같은 데이터타입끼리의 순서는 바꿀 수 없다! = 오버로딩 성립 X
// public void sum(int num2, int num1) {
// System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
// }
}
OverloadingMethod om = new OverloadingMethod();
// 반드시 호출하려는 메서드의 매개변수 갯수 및 타입이 일치해야함
om.print(10, 20);
om.print(10, 20, 30);
// om.print(10, 20, 30, 40); // 오류 발생!
om.print2(2, "홍길동", "이순신");
om.print2(3, "홍길동", "이순신", "강감찬");
om.print2(4, "홍길동", "이순신", "강감찬", "김태희");
// 정수 1개, 실수 1개를 전달받아 덧셈 결과를 출력하는 sum() 메서드
om.sum(1, 3.14);
om.sum(3.14, 1);
메서드 오버라이딩 Method Overriding
- 슈퍼클래스로부터 상속받은 메서드와 시그니쳐가 동일한 메서드를 서브클래스에서 새롭게 재정의 하는 것
- 기존의 슈퍼클래스의 메서드를 수정하여 덮어쓰는 것
- 오버라이딩 이후에는 슈퍼클래스의 메서드는 은닉되어 보이지 않음
- 오버라이딩을 ****사용하는 이유 코드의 재사용성이 향상되고, 통일성이 제공됨
- 오버라이딩 단축키 : Alt + Shift + S -> V 자동 오버라이딩을 ****수행하면 @Override 어노테이션이 붙게 됨 오버라이딩 규칙을 위반하면 오류가 발생하도록 함 (ex. 오버로딩, 오타로 인한 이름 입력 오류 등)
오버라이딩 작성 규칙
- 슈퍼클래스의 메서드 시그니쳐(이름, 파라미터, 리턴타입)가 완벽하게 동일해야한다.
- 슈퍼클래스 메서드의 접근제한자보다 범위가 좁아질 수 없다.
(ex. 슈퍼클래스가 public 이면 서브클래스도 public 이어야함)
(ex2. 만약 protected 이면 서브클래스는 protected, public 가능)
class Parent4 {
public void parentPrn() {
System.out.println("슈퍼클래스의 parentPrn() 메서드!");
}
}
// Child4 클래스 정의 - Parent4 클래스를 상속
class Child4 extends Parent4 {
public void childPrn() {
System.out.println("서브클래스의 childPrn() 메서드!");
}
// 슈퍼클래스로부터 상속받은 parentPrn() 메서드 오버라이딩
// => 리턴타입, 이름, 파라미터가 모두 동일해야함
// => 접근제한자는 좁아질 수 없음
public void parentPrn() {
System.out.println("서브클래스에서 오버라이딩 된 parentPrn() 메서드!");
}
}
class Car {
public void speedUp() {
System.out.println("자동차 속력 증가!");
}
public void speedDown() {
System.out.println("자동차 속력 감소!");
}
public void addFuel() {
System.out.println("자동차 연료 공급!");
}
}
// 디젤 자동차 - Car 클래스 상속
class DieselCar extends Car {
// Car 클래스의 메서드를 오버라이딩하여 DieselCar 만의 기능을 재정의
public void speedUp() {
System.out.println("DieselCar 방식으로 속력 증가!");
}
public void speedDown() {
System.out.println("DieselCar 방식으로 속력 감소!");
}
public void addFuel() {
System.out.println("주유소에서 디젤 연료 공급!");
}
}
// 전기 자동차 - Car 클래스 상속
class ElectricCar extends Car {
// Car 클래스의 메서드를 오버라이딩하여 ElectricCar 만의 기능을 재정의
// 자동 오버라이딩 단축키 : Alt + Shift + S -> V
@Override
public void speedUp() {
System.out.println("ElectricCar 방식으로 속력 증가!");
}
@Override
public void speedDown() {
System.out.println("ElectricCar 방식으로 속력 감소!");
}
@Override
public void addFuel() {
System.out.println("전기 충전소에서 배터리 충전!");
}
}
Child4 c = new Child4();
c.childPrn(); // 서브클래스에서 정의한 메서드
c.parentPrn(); // 서브클래스에서 오버라이딩 된 메서드
// => 슈퍼클래스(Parent4)의 parentPrn() 메서드는 보이지 않으므로
// 접근이 불가능하게 됨(은닉됨)
System.out.println("============================");
// Car 클래스를 상속받은 DieselCar 와 ElectricCar 클래스의
// 인스턴스를 생성하여 오버라이딩 된 메서드를 각각 호출
DieselCar dc = new DieselCar();
dc.speedUp();
dc.speedDown();
dc.addFuel();
ElectricCar ec = new ElectricCar();
ec.speedUp();
ec.speedDown();
ec.addFuel();
가변 인자(비정형 인자, Variable Arguments)
- 메서드 정의 시 파라미터(매개변수)에 전달되는 인자의 갯수가 유동적일 때 일정 갯수가 정해져 있지 않으므로 변수 선언이 어렵다. 따라서, 이렇게 동적인 인자의 갯수를 모두 처리할 수 있도록 가변 인자를 사용하여 변수를 선언하면 동일한 타입의 갯수가 제한이 없는 인자를 모두 전달받을 수 있음
- 가변 인자 형태로 선언되는 매개변수는 ****전달받은 데이터를 해당 이름을 가진 배열 형태로 관리함
- 가변 인자에 전달될 데이터는 0개부터 자유롭게 전달 가능
주의 사항!
가변 인자는 마지막 파라미터로 단 한 번만 사용 가능하다.
가변 인자를 사용한 메서드 정의 기본 문법
[제한자] 리턴타입 메서드명(데이터타입... 변수명) {
// => 전달되는 데이터들이 가변인자 변수명의 배열로 관리됨
}
class VariableArguments {
// 가변인자(비정형인자)를 활용한 메서드 오버로딩
// => 하나의 메서드 정의만으로 갯수가 다른 파라미터를 모두 처리 가능
public void varargsPrint(int...nums) {
// 외부로부터 전달되는 정수형 데이터는 갯수 제한 없이
// 모두 nums 이름을 갖는 배열에 저장됨
// => 반복문을 사용하여 배열 내의 모든 데이터에 접근 가능
// 1) 일반 for문
// for(int i = 0; i < nums.length; i++) {
// System.out.print(nums[i] + " ");
// }
// 2) 향상된 for문
for(int num : nums) {
System.out.print(num + " ");
}
System.out.println();
}
// 주의사항!
// 가변인자는 마지막 인자로 단 한 번만 사용 가능
public void varargsPrint2(String title, int...nums) {}
// => 가변인자 앞에 다른 매개변수가 있더라도, 마지막이 가변인자면 OK
// public void varargsPrint2(int...nums, String title) {} // 오류 발생!
// => 가변인자 뒤에 다른 매개변수가 올 수 없다!
// public void varargsPrint2(int...nums, String...title) {} // 오류 발생!
// => 가변인자 뒤에 다른 매개변수가 올 수 없으므로
// 2개 이상의 가변인자 사용도 불가능하다!
// ----------------------------------------------------------
// 일반 메서드 오버로딩
// 정수 2개(n1, n2)를 전달받아 출력하는 print() 메서드 정의
public void normalPrint(int n1, int n2) {
System.out.println(n1 + ", " + n2);
}
// 정수 3개(n1, n2, n3)를 전달받아 출력하는 print() 메서드 정의
public void normalPrint(int n1, int n2, int n3) {
System.out.println(n1 + ", " + n2 + ", " + n3);
}
// => 전달되는 데이터가 2개 또는 3개의 경우에만 메서드가 호출되고
// 0개, 1개, 또는 4개 이상의 경우에는 일치하는 매개변수가 없으므로
// 호출되지 못하고 오류가 발생한다!
}
VariableArguments va = new VariableArguments();
// va.normalPrint(); // 오류 발생
// va.normalPrint(10); // 오류 발생
va.normalPrint(10, 20);
va.normalPrint(10, 20, 30);
// va.normalPrint(10, 20, 30, 40); // 오류 발생
// 가변인자를 사용한 메서드 호출 시 전달할 파라미터 갯수 제한 없음
va.varargsPrint(10);
va.varargsPrint(10, 20);
va.varargsPrint(10, 20, 30);
va.varargsPrint(10, 20, 30, 40);
va.varargsPrint(); // 전달할 데이터가 없어도 호출 가능
728x90
반응형
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
[JAVA] 자바의 접근제한자 Access Modifier (0) | 2021.01.18 |
---|---|
[JAVA] 자바의 클래스 Class (0) | 2021.01.18 |
[JAVA] 자바의 배열 Array (0) | 2021.01.18 |
[JAVA] 자바의 반복문 for & while (0) | 2021.01.18 |
[JAVA] 조건문 if & switch (0) | 2021.01.18 |