3.8 기본형 매개변수와 참조형 매개변수
- 기본형 : 변수의 값을 읽기만 가능(값의 복사본)
- 참조형 : 변수의 값을 일고 변경 가능(값의 주소를 참조)
기본형 매개변수
package ch06;
class Data { int x; }
class PrimitiveParamEx {
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);
}
static void change(int x) { // 기본형 매개변수
x = 1000;
System.out.println("change() : x = " + x);
}
}
참조형 매개변수
package ch06;
// class Data { int x; }
class ReferenceParamEx {
public static void main(String[] args) {
Data d = new Data();
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);
}
static void change(Data d) { // 참조형 매개변수
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}
배열의 참조형 매개변수
package ch06;
class ReferenceParamEx2 {
public static void main(String[] args)
{
int[] x = {10}; // 크기가 1인 배열. x[0] = 10;
System.out.println("main() : x = " + x[0]);
change(x);
System.out.println("After change(x)");
System.out.println("main() : x = " + x[0]);
}
static void change(int[] x) { // 참조형 매개변수
x[0] = 1000;
System.out.println("change() : x = " + x[0]);
}
}
메서드로 배열을 다루는 여러 방법
package ch06;
class ReferenceParamEx3 {
public static void main(String[] args)
{
int[] arr = new int[] {3,2,1,6,5,4};
printArr(arr); // 배열의 모든 요소를 출력
sortArr(arr); // 배열을 정렬
printArr(arr); // 정렬후 결과를 출력
System.out.println("sum="+sumArr(arr)); // 배열의 총합을 출력
}
static void printArr(int[] arr) { // 배열의 모든 요소를 출력
System.out.print("[");
for(int i : arr) // 향상된 for문
System.out.print(i+",");
System.out.println("]");
}
static int sumArr(int[] arr) { // 배열의 모든 요소의 합을 반환
int sum = 0;
for(int i=0;i<arr.length;i++)
sum += arr[i];
return sum;
}
static void sortArr(int[] arr) { // 배열을 오름차순으로 정렬
for(int i=0;i<arr.length-1;i++)
for(int j=0;j<arr.length-1-i;j++)
if(arr[j] > arr[j+1]) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
} // sortArr(int[] arr)
}
반환값 없는 메서드 구현
package ch06;
class ReturnTest {
public static void main(String[] args) {
ReturnTest r = new ReturnTest();
int result = r.add(3,5);
System.out.println(result);
int[] result2 = {0}; // 배열을 생성하고 result2[0]의 값을 0으로 초기화
r.add(3,5,result2); // 배열을 add메서드의 매개변수로 전달
System.out.println(result2[0]);
}
int add(int a, int b) {
return a + b;
}
void add(int a, int b, int[] result) {
result[0] = a + b; // 매개변수로 넘겨받은 배열에 연산결과를 저장
}
}
3.9 참조형 반환타입
- 참조형 타입의 값은 객체의 주소 정수 값이므로 특별한 것이 없음
package ch06;
class Data3 { int x; }
class ReferenceReturnEx {
public static void main(String[] args)
{
Data3 d = new Data3();
d.x = 10;
Data3 d2 = copy(d);
System.out.println("d2" + d2.toString());
System.out.println("d.x ="+d.x);
System.out.println("d2.x="+d2.x);
}
static Data3 copy(Data3 d) {
Data3 tmp = new Data3();
tmp.x = d.x;
System.out.println("tmp" + tmp.toString());
return tmp;
}
}
3.10 재귀호출(recursive call)
- 메서드 내부에서 메서드 자신을 다시 호출 하는 것
- 메서드 호출이라는 것은 특정 위치의 저장되어 있는 명령을 수행 하는 것
- 대부분의 재귀호출은 반복문으로 가능
팩토리얼 구하기
- f(n) = n * f(n-1), 단 f(1) = 1
- 5! = 54321
package ch06;
class FactorialTest {
public static void main(String args[]) {
int result = factorial(4); // int result = FactorialTest.factorial(4);
System.out.println(result);
}
static int factorial(int n) {
int result=0;
if ( n == 1) {
result = 1;
} else {
result = n * factorial(n-1); // 다시 메서드 자신을 호출한다.
}
return result;
}
}
반복문 사용
package ch06;
class FactorialTestA {
public static void main(String args[]) {
int result = factorial(4); // int result = FactorialTest.factorial(4);
System.out.println(result);
}
static int factorial(int n) {
int result=1;
while(n != 0) {
result *= n--;
}
return result;
}
}
팩토리얼 최종
package ch06;
class FactorialTest2 {
static long factorial(int n) {
if(n<=0 || n>20) return -1; // 매개변수의 유효성 검사.
if(n<=1)
return 1;
return n * factorial(n-1);
}
public static void main(String args[]) {
int n = 21;
long result = 0;
for(int i = 1; i <= n; i++) {
result = factorial(i);
if(result==-1) {
System.out.printf("유효하지 않은 값입니다.(0<n<=20):%d%n", n);
break;
}
System.out.printf("%2d!=%20d%n", i, result);
}
} // main의 끝
}
x^1 ~ x^n 합 재귀함수로 구해보기
- f(x, n) = x * f(x, n-1), 단 f(x,1) = x
package ch06;
class PowerTest {
public static void main(String[] args) {
// 2^1 + 2^2 + 2^3 + 2^4 + 2^5
int x = 2;
int n = 5;
long result = 0;
for(int i=1; i<=n; i++) {
result += power(x, i);
}
System.out.println(result);
}
static long power(int x, int n) {
if(n==1) return x;
return x * power(x, n-1);
}
}
3.11 클래스 메서드(static 메서드)와 인스턴트 메서드
- 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static 사용
- 클래스 변수(static 변수)는 인스턴스를 생성하지 않아도 사용
- 클래스 메서드(static 메서드)는 인스턴스 변수 사용 불가
- 메서드 내에서 인스턴스 변수를 사용하지 않는 다면 static 사용 고려
package ch06;
class MyMath2 {
long a, b;
// 인스턴스변수 a, b만을 이용해서 작업하므로 매개변수가 필요없다.
long add() { return a + b; } // a, b는 인스턴스변수
long subtract() { return a - b; }
long multiply() { return a * b; }
double divide() { return a / b; }
// 인스턴스변수와 관계없이 매개변수만으로 작업이 가능하다.
static long add(long a, long b) { return a + b; } // a, b는 지역변수
static long subtract(long a, long b) { return a - b; }
static long multiply(long a, long b) { return a * b; }
static double divide(double a, double b) { return a / b; }
}
class MyMathTest2 {
public static void main(String args[]) {
// 클래스메서드 호출. 인스턴스 생성없이 호출가능
System.out.println(MyMath2.add(200L, 100L));
System.out.println(MyMath2.subtract(200L, 100L));
System.out.println(MyMath2.multiply(200L, 100L));
System.out.println(MyMath2.divide(200.0, 100.0));
MyMath2 mm = new MyMath2(); // 인스턴스를 생성
mm.a = 200L;
mm.b = 100L;
// 인스턴스메서드는 객체생성 후에만 호출이 가능함.
System.out.println(mm.add());
System.out.println(mm.subtract());
System.out.println(mm.multiply());
System.out.println(mm.divide());
}
}
3.12 클래스 멤버와 인스턴스 멤버간의 참조와 호출
- 클래스멤버가 인스턴스 멤버를 참조 또는 호출 하는 경우는 인스턴스 생성 필요
- 클래스멤버 존재 시점에 인스턴스 맴버 존재 하지 않기 때문
- static 메서드는 인스턴스 변수 사용 불가
package ch06;
class MemberCall {
int iv = 10;
static int cv = 20;
int iv2 = cv;
// static int cv2 = iv; // 에러. 클래스변수는 인스턴스 변수를 사용할 수 없음.
static int cv2 = new MemberCall().iv; // 이처럼 객체를 생성해야 사용가능.
static void staticMethod1() {
System.out.println(cv);
// System.out.println(iv); // 에러. 클래스메서드에서 인스턴스변수를 사용불가.
MemberCall c = new MemberCall();
System.out.println(c.iv); // 객체를 생성한 후에야 인스턴스변수의 참조가능.
}
void instanceMethod1() {
System.out.println(cv);
System.out.println(iv); // 인스턴스메서드에서는 인스턴스변수를 바로 사용가능.
}
static void staticMethod2() {
staticMethod1();
// instanceMethod1(); // 에러. 클래스메서드에서는 인스턴스메서드를 호출할 수 없음.
MemberCall c = new MemberCall();
c.instanceMethod1(); // 인스턴스를 생성한 후에야 호출할 수 있음.
}
void instanceMethod2() { // 인스턴스메서드에서는 인스턴스메서드와 클래스메서드
staticMethod1(); // 모두 인스턴스 생성없이 바로 호출이 가능하다.
instanceMethod1();
}
}
이전글
[JAVA] - chap 06 객체지향 프로그래밍 I(object-oriented programming I)_1
[JAVA] - chap 06 객체지향 프로그래밍 I(object-oriented programming I)_2
'JAVA > 객체지향 프로그래밍 I' 카테고리의 다른 글
객체지향 프로그래밍 I(object-oriented programming I)_4 (1) | 2018.08.17 |
---|---|
객체지향 프로그래밍 I(object-oriented programming I)_2 (0) | 2018.08.17 |
객체지향 프로그래밍 I(object-oriented programming I)_1 (1) | 2018.08.17 |