2023-01-17 09:30 ~ 18:30 수업진행
※ 수업내용
7) 메서드의 실행(호출)
메서드는 보통 하나의 기능 단위로 선언하고, 다른곳에서 그 기능이 필요할 때 실행하게 된다.
메서드를 실행하는 곳을 크게 같은 클래스 내부에서 호출하는 경우와 다른 클래스 외부에서 호출하는 경우로 나눌 수 있다.
클래스 내부에서 실행하는 경우는 그냥 메서드 이름만 적어주면 실행이 가능하다.
하지만 클래스 외부에서 메서드를 실행하는 경우는 먼저 해당 클래스를 객체로 생성한 후 객체를 통해 메서드를 실행해야 한다.
메서드를 실행할 때 주의할 점은 매개변수의 타입과 개수에 맞게 값을 넘겨줘야 한다. 그리고 리턴값 역시 값을 돌려 받을 때 리턴타입에 맞춰서 받아야한다.
매개변수의 타입과 리턴값의 타입이 자료형에서 형변환이 가능한 경우에만 실행이 가능하다.
메서드도 변수와 마찬가지로 클래스 메서드와 인스턴스 메서드가 있다.
클래스 메서드는 클래스 명으로 직접 실행이 가능하고, 인스턴스 메서드는 객체롤 통해 실행할 수 있다. 객체생성 없이 바로 실행할 수 있는 메서드는 선언부에 static을 붙여 주면 된다.
아래 예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
package chapter7;
public class MethodCall {
int i = 10; // 자료형타입인 int에 클래스변수 i를 선언하고 10값을 초기화, 객체를 생성해야 호출가능
static int si = 15; // 자료형타입인 int에 클래스변수 si를 선언하고 15값을 초기화, static이 있어 객체없이 호출 가능
public static void main(String[] args) { // 실행문
// 직접 실행
Method.printName(); // class Method에 있는 printName()메소드 호출, static이 있어 별도의 객체생성없이 호출 가능
// 객체를 생성해서 실행
Method m = new Method(); // 객체 생성
m.printEmail(); // class Method에 있는 printEmail() 메소드 호출
System.out.println(new MethodCall().i); // 객체 생성 후 출력
System.out.println(si); // static이 있기 때문에 객체 생성 없이 출력
}
}
class Method { // 호출대상
static void printName() {
System.out.println("printName() 실행");
}
void printEmail() {
System.out.println("printEmail() 실행");
printId(); // 다른 메서드 실행
// 매개가 없어도 같은 클래스 멤버이기 때문에 선언이 가능하다.
// 인스턴스 메서드는 클래스 메서드를 호출 가능하다.
}
void printId() {
System.out.println("printId() 실행");
}
}
|
cs |
8) 메서드의 실행순서
자료구조중에 스택(stack)이라는 자료구조가 있다.
이 스택은 가장 나중에 들어온 데이터가 가장 먼저 출력되는 자료구조이다. (Last In First Out)
위 그림처럼 input에서 1이 먼저 들어가고 2, 3순으로 저장이 되는데
스택이라는 자료구조는 1을 먼저 꺼낼 수가 없어 3을 먼저 꺼내게 된다.
따라서 output순서는 3, 2, 1 순이 된다. 이것을 스택 자료구조라고 한다.
메서드는 실행될 때 이 하나의 스택이라는 자료구조로 만들어진 메로리를 생성해서 실행한다.
메서드 내부에서 다른 메서드를 실행하면 스택에 저장된 상태에서 실행되기 때문에 스택처럼 먼저 실행된 메서드가 나중에 종료된다.
아래 예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
package chapter7;
public class MethodOrder {
public static void main(String[] args) {
MethodEx me = new MethodEx(); // 객체 생성
me.one(); // 메서드 실행
}
}
class MethodEx {
void one() { // 1
two();
System.out.println("one");
}
void two() { // 2
three();
System.out.println("two");
}
void three() { // 3
System.out.println("three");
}
}
|
cs |
main() 메서드에서 MethodEx me = new MethodEx()라는 객체를 생성하고
me.one() class MethodEx에 있는 one메서드를 실행한다.
one()메서드에서는 two()메서드를, two()메서드 에서는 three()메서드를 실행하는데. 실행 결과를 보면
three -> two -> one 순으로 출력이 되었다.
스택구조로 인해 나중에 실행된 메서드가 먼저 끝나게 된것이다.
9) 메서드 오버로딩 (Method Overloading)
클래스 내에서 이름이 같은 메서드가 여러개 있을 수 있는데 이것을 오버로딩이라고 한다.
간단하게 말해서 over과하게 load 적재하다 사전적으로는 과하게 많이 적재한다는 의미이다.
조금 더 확장해서 생각해보면 같은 이름을 가진 메서드 이면서 매개변수의 자료형, 매개변수의 개수, 순서중에 하나 이상이 달라야 한다.
매서드 오버로딩이 필요한 이유는 매개변수를 다양하게 입력받게 하기 위함이다.
예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package chapter7;
public class Overloading2 {
public static void main(String[] args) {
System.out.println();
System.out.println(1);
System.out.println(5.5);
System.out.println(5.5f);
System.out.println((long)100);
System.out.println("홍길동");
System.out.println('a');
System.out.println(true);
System.out.println(new Overloading2());
System.out.println(new int[5]);
System.out.println(new char[] {66,97,'c','가', '\uac01'});
}
}
|
cs |
어떤 값을 넣어도 출력이 되는 것을 알 수 있다.
7. 생성자 (Constructor)
생성자는 new 연사자와 함께 객체를 생성할 때 사용한다.
생성자는 메서드와 비슷하게 생겼지만, 클래스 이름과 생성자 이름이 항상 동일해야 하고, 리턴값이 없어서, 리턴타입을 아예 적어주지 않는다.
생성자는 객체(인스턴스)가 생성될 때 가장 먼저 실행되므로, 객체 내의 필드(변수)를 초기화 하거나, 객체를 사용하기 전에 준비하는 실행문을 생성자 블록 안에 넣는 경우가 많다.
즉, 생성자의 용도는 객체의 초기화 목적이다.
생성자의 구조를 살펴보자
클래스명 (매개변수...) {
초기화 실행문
...
}
생성자 명이 곧 클래스명이다. 생성자도 매개변수가 있을 수도 없고, 없을수도 있다. 중괄호 블록이 구분되며, 리턴값은 존재하지 않는다.
1) 기본 생성자
모든클래스는 생성자가 반드시 하나 이상 존재한다.
생성자를 만들지 않으면 컴파일시 자동으로 추가된다. 이것을 기본생성자라고 한다.
만약 매개변수(parameter)가 존재하는 생성자를 직접 작성한 경우 기본생성자는 자동으로 추가되지 않는다.
객체를 생성할 때 기본 생성자를 실행해서 객체를 생성시킬 수 있다.
Member member = new Member();
new연산자 뒤의 new Member()가 바로 기본생성자 이다.
2) 변수 초기화
기본생성자가 아닌 직접 생성자를 정의할 수 있는데, 생성자는 메서드와 비슷하게 생겼으나, 리턴값이 없고, 생성자명이 클래스명과 동일하다. 생성자의 용도는 객체를 생성할 때 초기화 하는 목적이다.
아래 예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package chapter7;
public class Student {
//클래스변수 선언
int no;
String name;
int kor;
int eng;
@Override
public String toString() {
//
return "Student [no = " + no + ", name = " + name + ", kor = " + kor + ", eng = " + eng + "]";
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
package chapter7;
public class StudentEx {
public static void main(String[] args) {
// 객체 생성
Student s1= new Student();
Student s2= new Student();
Student s3= new Student();
// 클래스변수 선언
s1.no = 1;
s1.name = "홍길동";
s1.kor = 80;
s1.eng = 80;
s2.no = 2;
s2.name = "김철수";
s2.kor = 90;
s2.eng = 95;
s3.no = 3;
s3.name = "이징징";
s3.kor = 80;
s3.eng = 90;
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
Student[] students = {s1, s2, s3};
//향상된 for문 사용
for (Student s : students) {
System.out.println(s);
}
// students의 0번 인덱스 출력
System.out.println(students[0]);
}
}
|
cs |

3) 생성자 오버로딩
앞에서 배웠던 메서드 오버로딩과 동일하다.
생성자는 객체를 초기화 할때 필요한 다양한 매개변수들이 필요한데, 매개변수 타입이나 개수가 다른 동일한 이름의 생성자를 사용해 여러개를 정의할 수 있다.
7. this
1) this 생성자
같은 클래스의 메서드를 실행할 수 있는것처럼 생성자 간에도 서로 실행이 가능하다.
이때 생성자명 대신 this라는 키워드를 사용한다.
주의할점은 다른 생성자를 실행할 때는 반드시 첫줄에서 실행해야 한다.
this키워드가 사용되는 또 하나는 참조변수로서 객체 자기자신을 가리킨다.
객체 외부에서 객체 내의 멤버에 접근하기위해 객체변수(참조변수)를 사용하듯이 객체 내부에서도 객체의 멤버에 접근하기 위해 this 키워드를 사용한다. this는 객체 자신이라고 생각하면 되고, 미래에 생성될 객체의 주소값 이라고 외우면 된다.
아래 예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package chapter7;
public class Car2 {
//필드
String color;
String company;
String type;
Car2() {
this("White", "기아", "경차");
// System.out.println(0);
}
Car2(String color, String company, String type) {
this.color = color;
this.company = company;
this.type = type;
// System.out.println(3);
}
Car2(String com, String t) {
this("white", com, t);
// System.out.println(2);
}
Car2(String t) {
this("white", "기아", t);
// System.out.println(1);
}
public String toString() {
return color + "-" + company + "-" + type;
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
package chapter7;
public class Car2Main {
public static void main(String[] args) {
Car2 c1 = new Car2();
Car2 c2 = new Car2("중형차");
Car2 c3 = new Car2("현대", "대형차");
Car2 c4 = new Car2("black", "기아", "화물차");
System.out.println("c1 = "+c1);
System.out.println("c2 = "+c2);
System.out.println("c3 = "+c3);
System.out.println("c4 = "+c4);
}
}
|
cs |
Car2 클래스에 총 4개의 생성자가 있는데 ( Car2() ) this() 키워드를 사용해 매개변수가 3개인 생성자를 실행하고있다.
메소드 내에서 변수 이름을 이용할 때 아무런 설정이 없으면 블록내에서 먼저 찾고 블록에 없으면 바깥쪽 블록으로 이동하면서 찾는다.
this를 붙이면 메소드 외부, 즉 자신의 클래스에 만든 변수 그리고 상위 클래스에 만들어진 변수 순서대로 찾는다.
객체를 초기화 하거나, 필드에 값을 세팅하는 경우 자주 사용되는 구문이다.
8. 초기화 블록
초기화 블록은 static초기화 블록과 인스턴스 초기화 블록이 있다
.
static초기화 블록은 클래스가 메모리에 로드 될 때 단 한번 실행된다.
로드순서가 생성자보다 빠르다.
클래스를 초기화 할때마다 사용된다 (변수 초기화와 비슷함)
인스턴스 초기화 블록은 객체가 생성될 때 마다 실행되는 블록이다.
인스턴스 초기화 블록은 인스턴스가 초기화 될 때 마다 실행한다.
초기화 블록은 생성자 보다도 먼저 실행된다. 예제를 보자
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package chapter7;
public class InitEx {
//생성자
InitEx() {
System.out.println("생성자 호출");
}
//static 초기화블럭, 가장 먼저 실행됨
static {
System.out.println("클래스 초기화 블럭 실행");
}
//인스턴스 초기화 블럭
{
System.out.println("인스턴스 초기화 블럭 실행");
}
public static void main(String[] args) {
System.out.println("main 메서드시작");
System.out.println("main init1 객체 생성");
InitEx init1 = new InitEx();
System.out.println("main init2 객체 생성");
InitEx init2 = new InitEx();
}
}
|
cs |
자바 프로그램이 실행되면 실행되는 소스가 main() 메서드에 있는 소스인데, 예제에서는 main메서드보다 static 중괄호 블럭이 먼저 실행된 것을 볼 수 있다.
간단하게 출력 순서를 확인 해 보면
static 초기화 블록 실행 -> main메서드 실행 -> 인스턴스 초기화 블록 실행 -> 셍상지 실행 순이다.
static 초기화 블록은 처음 한번만 메모리에 로드 되기 때문에 단 한번 실행 후 더이상 실행하지 않는다.
다음은 순서에 따라 출력되고 프로그램이 종료되었다.
초기화 블록은 static이 붙은 블록과 그렇지 않은 블록이 있는데 클래스에 고정된 멤버이다.
주의할 점은 객체 생성 없이도 실행되기 때문에 블록내 인스턴스 변수나, 인스턴스 메서드, this를 사용할 수 없다.
초기화 블록을 끝으로 23-01-17 수업내용 정리를 마치겠다.
'JAVA' 카테고리의 다른 글
23-01-30(2) 자바 (system클래스, class 클래스, String 클래스) (0) | 2023.01.30 |
---|---|
23-01-18 수업내용 정리 (0) | 2023.01.18 |
23-01-16 수업내용 정리 (0) | 2023.01.16 |
23-01-12 수업내용 정리 (0) | 2023.01.15 |
23-01-13 수업내용 정리 (0) | 2023.01.15 |