⦁ 메소드란?
1. 문장들을 묶어놓은 것.
- 작업단위로 문장들을 묶어서 이름을 붙인 것
2. 값(입력)을 받아서 처리하고, 결과를 반환(출력)
⦁ 메소드의 장점
- 코드의 중복을 줄일 수 있다.
- 코드의 관리가 쉽다.
- 코드를 재사용할 수 있다.
- 코드가 간결해서 이해하기 쉬워진다.
⦁ 메소드의 작성
- 반복적으로 수행되는 여러 문장을 메소드로 작성
- 하나의 메소드는 한 가지 기능만 수행하도록 작성
메소드 = 선언부 + 구현부
반환타입 메소드이름 (타입 변수명, 타입 변수명, ...) // 선언부 {
// 메소드 호출시 수행될 코드 -> 구현부
}
int add (int a, int b) // 선언부 {
// 구현부 내용
int result = a + b;
return result; // 호출한 메소드로 result를 반환(return)한다.
}
지역변수(lv) : 메소드 내에 선언된 변수, 매개변수도 지역변수다.
⦁ 메소드의 호출
메소드이름(값1, 값2, ...); // 메소드를 호출하는 방법
print99danAll(); // void print99danAll()을 호출
int result = add(3, 5); // int add(int x, int y)를 호출하고, 결과를 result에 저장
ex)
class MyMath {
long add(long a, long b) {
long result = a + b;
return result;
// return a+b; // 위의 두줄을 이와 같이 한 줄로 간단히 할 수 있다.
}
long subtract(long a, long b) {
return a - b;
}
long multiply(long a, long b) {
return a * b;
}
double divide(double a, double b) {
return a / b;
}
// 두 값을 받아서 둘중에 큰 값을 반환하는 메소드를 작성하시오.
double max (double a, double b) {
return (a>b ? a : b);
}
}
public class Ex6_4 {
public static void main(String[] args) {
MyMath mm = new MyMath();
double result = mm.max(5, 3); // 둘 중에 큰 값을 반환하는 메소드
long result1 = mm.add(5L, 3L);
long result2 = mm.subtract(5L, 3L);
long result3 = mm.multiply(5L, 3L);
double result4 = mm.divide(5L, 3L);
System.out.println("max(5,3) = " + result);
System.out.println("add(5L, 3L) = " + result1);
System.out.println("subtract(5L, 3L) = " + result2);
System.out.println("mutliply(5L, 3L) = " + result3);
System.out.println("divide(5L, 3L) = " + result4);
}
}
⦁ 메소드의 실행흐름

① main메소드에서 메소드 add를 호출한다. 인수 1L과 2L이 메소드 add의 매개변수 a,b에 각각 복사(대입)된다.
② 메소드 add의 괄호{} 안에 있는 문장들이 순서대로 수행된다.
③ 메소드 add의 모든 문장이 실행되거나 return문을 만나면, 호출한 메소드(main메소드)로 되돌아와서 이후의 문장들을 실행한다.
⦁ return문
실행중인 메소드를 종료하고 호출한 곳으로 되돌아간다.
void printGugudan(int dan) {
if(!(2<=dan&&dan<=9))
return; // dan의 값이 2~9가 아닌 경우, 호출한 곳으로 그냥 되돌아간다.
for(int i=1;i <= 9;i++) {
System.out.printf(“%d * %d = %d%n”, dan, i, dan * I );
}
// 반환 타입이 void이므로 return 생략가능.
}
반환타입이 void가 아닌 경우, 반드시 return문 필요
int multiply (int x, int y) {
int result = x * y;
return result; // 반환 타입이 void가 아니므로 생략불가
}
int max(int a, int b) {
if(a > b)
return a; // 조건식이 참일 때 실행된다.
else
return b; // 조건식이 거짓일 때 실행된다.
}
ex) return문을 활용한 구구단 추가
class MyMath {
long add(long a, long b) {
long result = a + b;
return result;
// return a+b; // 위의 두줄을 이와 같이 한 줄로 간단히 할 수 있다.
}
long subtract(long a, long b) {
return a - b;
}
long multiply(long a, long b) {
return a * b;
}
double divide(double a, double b) {
return a / b;
}
// 두 값을 받아서 둘중에 큰 값을 반환하는 메소드를 작성하시오.
double max (double a, double b) {
if (a>b) {
return a; // 조건식이 참일때만 실행
} else {
return b; // 조건식이 거짓일 때 실행
}
}
void printGugudan(int dan) {
if(!(2<=dan && dan <=9)) {
return; // 입력받은 단(dan)이 2~9가 아니면, 메소드 종료하고 돌아가기
}
for(int i=1; i<=9; i++) {
System.out.printf("%d * %d = %d%n", dan, i, dan * i);
}
// return; 생략 가능
}
}
public class Ex6_4 {
public static void main(String[] args) {
MyMath mm = new MyMath();
double result = mm.max(5, 3); // 둘 중에 큰 값을 반환하는 메소드
long result1 = mm.add(5L, 3L);
long result2 = mm.subtract(5L, 3L);
long result3 = mm.multiply(5L, 3L);
double result4 = mm.divide(5L, 3L);
mm.printGugudan(5); // 구구단 5단을 출력
System.out.println("max(5,3) = " + result);
System.out.println("add(5L, 3L) = " + result1);
System.out.println("subtract(5L, 3L) = " + result2);
System.out.println("mutliply(5L, 3L) = " + result3);
System.out.println("divide(5L, 3L) = " + result4);
}
}
⦁ 반환값
반환타입이 void가 아닐 때, return값이 필요함.
타입이 일치해야 하며, 자동형변환이 된다.
⦁ 호출 스택(call stack)
스택(stack): 밑이 막힌 상자. 위에 차곡차곡 쌓인다.
메소드 수행에 필요한 메모리가 제공되는 공간
메소드가 호출되면 호출스택에 메모리 할당, 종료되면 해제
⦁ 기본형 매개변수와 참조형 매개변수
기본형 매개변수 – 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 – 변수의 값을 읽고 변경할 수 있다.(read & write)
ex) 기본형 매개변수
class Data {
int x;
}
public class Ex6_6 {
static void change(int x) { // 기본형 매개변수
x = 1000;
System.out.println("change() : x = " + x);
}
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d.x);
System.out.println("After change(d.x)");
System.out.println("main() : x = " + d.x);
}
}
ex) 참조형 매개변수
class Data2 {
int x;
}
public class Ex6_7 {
static void change(Data2 d) { // 참조형 매개변수
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
public static void main(String[] args) {
Data2 d = new Data2();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d);
System.out.println("After change(d)");
System.out.println("main() : x = " + d.x);
}
}
ex) 참조형 반환타입
class Data3 {
int x;
}
public class Ex6_8 {
static Data3 copy(Data3 d) { // 참조형 반환타입
Data3 tmp = new Data3(); // 새로운 객체 tmp를 생성한다.
tmp.x = d.x; // d.x의 값을 tmp.x에 복사한다.
return tmp; // 복사한 객체의 주소를 반환한다.
}
public static void main(String[] args) {
Data3 d = new Data3();
d.x = 10;
Data3 d2 = copy(d);
System.out.println("d.x=" + d.x);
System.out.println("d2.x=" + d2.x);
}
}
⦁ static 메소드와 인스턴스 메소드
- 인스턴스 메소드
인스턴스 생성 후, ‘참조변수.메소드이름()’으로 호출
인스턴스 멤버(iv, im)와 관련된 작업을 하는 메소드
메소드 내에서 인스턴스 변수 사용가능
- static 메소드(클래스 메소드)
객체생성없이 ‘클래스이름.메소드이름()’으로 호출
인스턴스 멤버(iv, im)와 관련없는 작업을 하는 메소드
메소드 내에서 인스턴스 변수 사용불가
iv 사용 여부가 둘의 차이이다.
⦁ static을 언제 붙여야 할까?

★인스턴스 멤버(iv,im)을 사용하지 않는 메소드에 static을 붙인다★
class MyMath2 {
long a, b;
long add() {
return a+b; // a, b는 인스턴스 변수
}
static long add(long a, long b) {
return a+b; // a, b는 지역 변수
}
⦁ 메소드 간의 호출과 참조
static 메소드는 인스턴스 변수(iv)를 사용할 수 없다.
class TestClass2 {
int iv; // 인스턴스 변수
static int cv; // 클래스 변수, 언제나 사용 가능
void instanceMethod() { // 인스턴스 메소드
System.out.println(iv); // 인스턴스 변수를 사용할 수 있다.
System.out.println(cv); // 클래스 변수를 사용할 수 있다.
}
static void staticMethod() { // static 메소드
System.out.println(iv); // 에러, 인스턴스 변수를 사용할 수 없다.
System.out.println(cv); // 클래스 변수는 사용할 수 있다.
}
}
static 메소드는 인스턴스 메소드(im)를 호출할 수 없다.
⦁ 오버로딩 (overloading)
한 클래스 안에 같은 이름의 메소드를 여러개 정의하는 것
⦁ 오버로딩이 성립하기 위한 조건
1. 메소드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
3. 반환 타입은 영향 없다.
보기1 (오버로딩 x, 메소드 중복정의)
int add(int a, int b) {
return a+b;
}
int add(int x, int y) {
return x+y;
}
보기2 (오버로딩 x, 반환 타입만 다른 중복정의)
int add(int a, int b) {
return a+b;
}
long add(int a, int b) {
return (long)(a+b);
}
보기3 (오버로딩o, 하지만 add(3,3) 하면 둘 다 가능하기 때문에 모호하게 됨 - ambiguous)
long add(int a, long b) {
return a+b;
}
long add(long a, int b) {
return a+b;
}
ex) 오버로딩의 예
class MyMath3 {
int add(int a, int b) {
System.out.print("int add(int a, int b) - ");
return a+b;
}
long add(int a, long b) {
System.out.print("long add(int a, long b) - ");
return a+b;
}
long add(long a, int b) {
System.out.print("long add(long a, int b) - ");
return a+b;
}
long add(long a, long b) {
System.out.print("long add(long a, long b) - ");
return a+b;
}
int add(int[] a) {
System.out.print("int add(int[] a) - ");
int result = 0;
for (int i=0; i < a.length; i++) {
result += a[i];
}
return result;
}
}
public class Ex6_10 {
public static void main(String[] args) {
MyMath3 mm = new MyMath3();
System.out.println("mm.add(3,3) 결과:" + mm.add(3,3));
System.out.println("mm.add(3L,3) 결과:" + mm.add(3L,3));
System.out.println("mm.add(3,3L) 결과:" + mm.add(3,3L));
System.out.println("mm.add(3L,3L) 결과:" + mm.add(3L,3L));
int[] a = {100, 200, 300};
System.out.println("mm.add(a) 결과:" + mm.add(a));
}
}
⦁ 생성자(constructor) = iv 초기화 메소드
- 인스턴스가 생성될 때마다 호출되는 ‘인스턴스 초기화 메소드’
- 인스턴스 생성시 수행할 작업(iv 초기화)에 사용
- 생성자의 이름이 클래스 이름과 같아야 한다.
- 리턴값이 없다.(void 안 붙임)
- 모든 클래스는 반드시 생성자를 가져야 한다.
⦁ 기본 생성자(default constructor)
- 매개변수가 없는 생성자
- 생성자가 하나도 없을 때만, 컴파일러가 자동으로 추가함
(기본 생성자는 클래스를 만들 때 꼭 필요함. 넣어주는 습관을 들이자)
클래스이름() {} // 기본 생성자
Point() {} // Point 클래스의 기본 생성자
ex)
class Data_1 {
int value;
Data_1(){} // 기본생성자를 추가
}
class Data_2 {
int value;
Data_2(){}
Data_2(int x) { // 매개변수가 있는 생성자
value = x;
}
}
public class Ex6_11 {
public static void main(String[] args) {
Data_1 d1 = new Data_1();
Data_2 d2 = new Data_2(); // compile error 발생, 기본생성자 필요
}
}
⦁ 매개변수가 있는 생성자
class Car {
String color; // 색상
String gearType; // 변속기 종류 – auto(자동), manual(수동)
int door; // 문의 개수
Car() {} // 기본 생성자
Car(String c, String g, int d) { // 매개변수가 있는 생성자
color = c;
gearType = g;
door = d;
}
}
ex)
class Car {
String color;
String gearType;
int door;
Car() {}
Car(String c, String g, int d) {
this.color=c;
this.gearType=g;
this.door=d;
}
}
public class Ex6_12 {
public static void main(String[] args) {
Car c1 = new Car();
c1.color = "white";
c1.gearType = "auto";
c1.door = 4;
Car c2 = new Car("blue","auto",2);
System.out.println("c1의 color = " + c1.color + ", gearType = " + c1.gearType + ", door = " + c1.door);
System.out.println("c2의 color = " + c2.color + ", gearType = " + c2.gearType + ", door = " + c2.door);
}
}
⦁ 생성자 this()
- 생성자에서 다른 생성자 호출할 때 사용
- 다른 생성자 호출시 첫 줄에서만 사용가능

⦁ 참조변수 this
- 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다.
- 인스턴스 메소드(생성자 포함)에서 사용가능
- 지역변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용
⦁ 변수의 초기화
- 지역변수(lv)는 수동 초기화 해야함(사용전 꼭!!!)
- 멤버변수(iv, cv)는 자동으로 초기화 된다.
class InitTest {
int x; // 인스턴스 변수, 자동으로 0으로 초기화 됨.
int y = x; // 인스턴스 변수
void method1() {
int i; // 지역변수
int j = i ; // 에러, 지역변수를 초기화하지 않고 사용했기 때문.
}
}
⦁ 멤버변수(iv, cv)의 초기화
1. 명시적 초기화(=)
class Car {
int door = 4; // 기본형 변수의 초기화
Engine e = new Engine(); // 참조형 변수의 초기화
}
2. 초기화 블록 (복잡한 초기화)
- 인스턴스 초기화 블록 : { }
- 클래스 초기화 블록 : static { }
3. 생성자 (iv 초기화, 복잡한 초기화)
Car(String color, String gearType, int door) {
this.color = color;
this.gearType = gearType;
this.door = door;
}
⦁ 멤버변수의 초기화 – static { }
1. 명시적 초기화(=)
2. 초기화 블록 - { }, static { }
3. 생성자(iv초기화)
class StaticBlockTest {
static int[] arr = new int[10]; // 명시적 초기화
static { // 클래스 초기화 블록 – 배열 arr을 난수로 채운다.
for(int I=0; i<arr.length; I++ {
arr[i] = (int)(Math.random()*10)+1;
}
}
}
클래스 변수 초기화 시점 : 클래스가 처음 로딩될 때 단 한번(메모리에 올라갈 때)
인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때 마다
초기화 순서
① cv -> iv
② 자동(0)->간단(=)->복잡 (static{ }, 생성자)
출처 : 남궁성의 정석코딩 유튜브
'Java > Java의 정석' 카테고리의 다른 글
220309 Java - Chapter 7. 객체지향개념 II Part.2 (0) | 2022.03.10 |
---|---|
220308 Java - Chapter 7. 객체지향개념 II Part 1 (0) | 2022.03.09 |
220305 Java - Chapter 6. 객체지향 개념I Part.1 (0) | 2022.03.05 |
220304 Java - Chapter 5. 배열 (0) | 2022.03.04 |
220303 Java - Chapter 4. 조건문 (0) | 2022.03.03 |