[Java] 클래스 메소드 문제
먼저 저번 시간에 배운 메소드를 활용해서 문제를 몇가지 풀어보겠습니다!
정수 5개를 입력하고 최소값과 최대값을 구해주는 메소드를 만들어 보고 실행해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
void getMaxAndMin(int[] nums, int[] result) {
int max = nums[0];
int min = nums[0];
for (int i = 1; i < nums.length; i++) {
if(max < nums[i]) { max = nums[i]; }
if(min > nums[i]) { min = nums[i]; }
}
result[0] = max;
result[1] = min;
}
먼저 타입은 void타입으로 리턴값이 없는 메소드를 만들었습니다. 아니 최대값과 최소값을 구하는데 리턴이 있어야 되는거 아냐? 라고 생각할 수있는데 리턴값을 설정하면 1개밖에 값을 설정하지 못합니다. 따라서 2개이상의 값을 주는 함수를 만들어야 하는데 이때 우리는 배열을 씁니다.
뭔가 이상하죠? 매개변수들을 보면 int[] nums, in[] result 같이 배열이 들어간 것을 볼 수 있었습니다. 왜 일까요? 그냥 정수 타입으로 하면 안 될까요? 정답은 주소값에 있습니다. 단순한 값을 갖고 있는 변수는 한 지역에서 선언 사용이 된다면 다른 지역에서는 쓸 수가 없습니다. 하지만 배열을 사용해 주소값을 주고 받고 그 값을 수정시킨다면 다른 지역에서도 사용이 가능하죠. 그래서 주소값을 갖고 있는 배열을 사용한 것입니다.
그리고 이 메소드에 int 타입의 변수 max, 와 min을 설정하고 nums배열의 첫번째 값을 대입시켜줍니다. 그리고 for문을 이용하여 조건문으로 큰값을 max에 작은값을 min에 넣어줍니다. 그리고 result[]에 각각 max와 min값을 넣었습니다. 이제 메인 메소드에서 사용해봅시다.
1
2
3
4
5
6
7
int[] result = new int[2];
int[] nums = {3, 2, 5, 7, 8};
m.getMaxAndMin(nums, result);
System.out.println("최대값 : " + result[0]);
System.out.println("최소값 : " + result[1]);
메인메소드에서 result 배열을 선언했습니다. 그리고 nums 배열을 선언해준뒤 값을 제 맘대로 설정했습니다!
그리고 아까 만든 메소드를 사용했습니다. 그리고 result 배열을 출력하면
잘 나오죠? 다른 지역에 있는 메소드에서 값을 수정했는데 메인메소드에서 그것을 출력할 수있다는 것은 배열은 자기의 고유한 주소를 갖고 있다는 뜻입니다. 그리고 그 주소값을 찾아들어가서 result배열에 값을 넣었으니 바뀔 수 밖에 없는 것이죠! 재밌습니다 ㅎㅎ
다음 문제는 한글로 숫자를 입력하면 (예: 구일공삼) 그것을 정수로 바꾸어 주는 메소드를 만들어보겠습니다.
1
2
3
4
5
6
7
8
long changeToInteger(String hangle) {
String hangleOrigin = "공일이삼사오육칠팔구";
String result = "";
for (int i = 0; i < hangle.length(); i++) {
result += hangleOrigin.indexOf(hangle.charAt(i));
}
return Long.parseLong(result);
}
먼저 String 타입의 매개변수 hangle을 설정합니다. 그리고 hangleOrigin의 문자열을 만들고 공~구까지의 한글을 넣어서 초기화 시켰습니다. 그리고 결과가 나올값은 result로 하겠습니다.
for문을 만들고 i 는 0부터 우리가 입력한 hangle 의 길이값까지 설정했습니다. 그런데 저 .indexOf()는 어떤 메소드 일까요?
charAt()은 그 문자열의 위치값(숫자)를 입력하면 그 위치로 가서 그 값을 가져오는 건데 indexOf는 그 반대로 값을 입력하면 그 값을 처음으로 만난 위치값(숫자)를 리턴합니다. 그래서 hangle에서 0번째 값(첫번째)을 hangleOrigin에서 찾고 그 위치값 (숫자)를 반환하니 결국 정수로 표현이 되겠죠? 그런식으로 만들었습니다. 메소드 타입을 int로 안 한 이유는 값이 너무 커지면 int에서 4바이트를 넘어가니 long으로 만들었습니다.
한번 사용해보죠.
1
System.out.println(m.changeToInteger("삼오육구공사칠팔오칠구공공구구칠칠"));
잘나오죠? 재밌습니다!
*클래스
하.. 클래스 되게 처음엔 어려웠습니다. 그런데 복습하고 했던거 살펴보니까 할만하더라고요!
1. 하나의 타입이다.
클래스안에 필드를 한 번만 선언하면 여러 군데에서 접근하여 사용할 수 있습니다. 하지만, 해당 클래스의 필드를 접근하기 위해서는 그 타입의 변수가
필요합니다.
2. 주어이다.
클래스는 대문자로 시작하잖아요.. 그리고 영어 문장의 첫단어는 대문자! 예를 들어
Monkey.eat(“바나나”);
라고 한다면 eat은 소괄호가 있으니까 메소드겠죠? 그리고 저번시간에 메소드는 보통 동사로 이름을 짓는다 합니다. 그리고 변수는 명사로 이름을 짓죠. 그래서 합쳐서 보면 하나의 영어문장이 되었습니다!! 클래스까지 배우니까 이런 것들이 합쳐져서 깨달음이 왔습니다 ㅎㅎㅎ
클래스 선언
class 클래스명{
필드(변수,메소드)
}
클래스 선언 시 내부적으로 기본 생성자가 선언됩니다.
만약 직접 생성자를 선언하게 되면 직접 선언한 생성자가 기본 생성자로 되겠죠? 클래스를 한번 선언해보겠습니다.
1
2
3
4
5
class Car{
String brand;
String color;
int price;
}
Car라는 클래스를 만들었습니다. 그리고 여기에 문자열 brand와 color, 정수타입의 price라는 필드를 만들었습니다. 필드는 메소드도 가능합니다.
이제 이걸 메인메소드에서 사용해야겠죠?
생성자
1. 해당 클래스의 필드를 메모리에 할당한 후 할당된 필드의 주소값을 리턴합니다.
2. 초기화합니다.
클래스 사용
추상적인 개념은 필드에 접근할 수 없다. 따라서 구체화된 무언가가 필요하며, 이를 객체라고 한다.
객체를 만드는 작업을 객체화라고 하며 instance라고도 부른다.
클래스명 객체명 = new 생성자();
1
Car mom = new Car();
이건 메인메소드에서 사용한겁니다. 일단 Car라는 클래스를 사용하기 위해서 적었습니다. 객체이름은 mom으로 했습니다. 엄마차 ㅋㅋ;
그 다음 new연산자로 힙메모리에 넣어줄 생성자 Car();를 사용했습니다. 잉? 생성자를 선언한적 없는데 왜 사용이죠? 답은 기본생성자에 있습니다. 우리가 직접 생성자를 만들지 않으면 기본 생성자를 사용하게 되고 기본 생성자는 클래스를 선언할 때 자동으로 생성됩니다.
만약 기본생성자를 쓴다면 메인메소드에
1
2
3
mom.brand = "Benz";
mom.color = "Black";
mom.price = 8000;
이런식으로 일일이 선언과 초기화를 해야하겠죠.. 너무 번거롭죠? 클래스를 사용하는 의미도 없을 겁니다.
그래서 직접 생성자를 사용하는거죠.
1
Car mom = new Car("Benz","Black",8000);
생성자에 저런식으로 필드를 넣어줄 수 있고 저 값으로 초기화를 할 수 있습니다. 그러면 오류가 납니다.. 그 이유는 저렇게 적는 순간 직접 생성자가 되기 때문에 기본생성자처럼 바로 사용할 수가 없는거죠.. 그래서 클래스 안에 직접 생성자를 선언해줍니다.
1
2
3
4
5
6
Car(String brand, String color, int price) {
this.brand = brand;
this.color = color;
this.price = price;
}
클래스 지역에 만들었습니다. 생성자는 메소드랑 문법이 같아서 메소드처럼 보이죠? 그래서 매개변수에 필드와 같이 선언하고 그다음에 읭? this. 가 뭔가요?this가 없으면 brand(클래스 필드) 에 brand(직접생성자 매개변수)를 대입해야 해서 brand = brand; 가 되어버립니다. 그렇다고 이름을 달리하면 객체가 많아질 때 헷갈리게 되죠.. 그래서 생성자의 매개변수랑 각 객체가 가지는 필드와 구분할 필요가 있고 그래서 this를 사용합니다.
this
외부에서 여러 개의 객체가 접근할 때 현재 접근한 객체가 어떤 객체인지 알아야 해당 필드에 접근할 수 있습니다.
접근한 객체가 가지고 있는 주소값을 this라는 변수에 자동으로 담은 후 this.필드명으로 접근하여 사용합니다.
저도 처음에 이런 것들을 들을 때 엄청 헷갈리더라고요.. 그래도 하나씩 해보면 재밌습니다!
클래스는 복잡하고 그만큼 양도 많은거라 앞으로도 포스팅할 때 종종 그 클래스가 나오면 언급하도록 하겠습니다 ^^
Comments powered by Disqus.