// 파라미터 전달 방법
public class Ex04_method {
public static void main(String[] args) {
Test4 tt = new Test4();
int n = 5;
// call by value
tt.sub1(n);
System.out.println(n); // 5
// call by reference
tt.sub2(tt); // tt객체의 주소값을 보냄
System.out.println(tt.x); // 15
int []ss = {10,20,30};
tt.sub3(ss);
System.out.println(ss[1]);
// 실인수와 가인수의 자료형은 같아야함.
}
}
class Test4 {
int x=10;
// call by value(기본) : 실매개 변수와 형식 매개변수가 기억공간 따로 확보
public void sub1(int a) {
a = a+10;
}
// call by reference : 레퍼런스변수(객체)
public void sub2(Test4 t) { // tt의 주소값을 t가 받음. 자료형이 Test4임.
// 보내는 것이 Test4의 레퍼런스변수 이므로 Test4의 레퍼런스변수로 받아야함
// 다시만드는 것이 아님. 메모리할당이 아님.
t.x +=5;
}
// call by reference : 레퍼런스변수(배열)
public void sub3(int[] nn) {
nn[1] += 100;
}
}
public class Ex03_method {
public static void main(String[] args) {
Rect r = new Rect();
int a, b;
r.width = 10;
r.height = 5;
a = r.area();
b = r.length();
System.out.println("넓이:"+a+", 둘레:"+b);
}
}
/*
- 직사각형의 넓이와 둘레계산
- 데이터(상태) : 가로, 세로
- 메소드 : 넓이계산, 둘레계산
*/
class Rect {
int width;
int height;
// 필드 선언 시, 자료형이 같아도 따로따로 선언한다.
// 넓이
public int area() {
return width * height;
}
// 둘레
public int length() {
return (width + height) * 2;
}
}
public class Ex01_field {
public static void main(String[] args) {
Test1 t1 = new Test1(); // 객체 생성. Test1 클래스의 a와 b필드가 메모리 할당받음.
Test1 t2 = new Test1();
t1.a=50;
System.out.println(t1.a+ " : " + t2.a); // 50:0
int s = t1.sub(10); // 지역변수와 매개변수는 호출 될 때 메모리 할당을 받음.
System.out.println(s);
s = t1.sub(100);
System.out.println(s);
/*
// 클래스 변수를 객체를 통해서 접근 가능 하지만 권장하지 않음. (경고)
t1.c = 50;
System.out.println(t1.c+ " : " + t2.c); // 50:50 메모리 할당이 한 번만 되어서
*/
System.out.println(Test1.c); // 클래스 변수는 클래스명으로 접근
}
}
class Test1 {
// 필드 : 인스턴스 변수 + 클래스 변수
// 인스턴스 변수
// 인스턴스 변수는 객체가 생성될 때 메모리가 생성. 메모리를 할당 받을 때 기본값으로 초기화
// 인스턴스 변수는 객체마다 메모리할당. heap 메모리 영역에 메모리할당 (자바가 메모리관리하는 부분임, 개발자가 관리 불가)
// 인스턴스 변수는 객체가 null이 되거나 오랫동안 사용되지 않으면 Garbage collector가 메모리회수.
// 객체에 종속되므로 객체를 통해서 접근 "객체명.인스턴스 변수" 로 접근
int a; // 생성될때 0으로 초기화
int b=10; // 생성될때 10으로 초기화
// 클래스 변수
// 클래스가 로딩될 때 메모리 할당.
// 객체 생성과 상관없이 하나만 메모리할당되고 모든 객체가 공유.
// "클래스명.클래스 변수"로 접근
// 프로그램이 종료되는 시점에 메모리에서 제거된다.
static int c=100;
// 매개변수, 지역변수 : 스택메모리 영역에 메모리 할당. 초기화하지 않으면 쓰레기값
// 매개변수와 지역변수는 메소드를 호출할 때 메모리가 할당된고 메소드를 빠져나가면 메모리에서 제거됨.
// 인스턴스 메소드 : 객체가 생성되어야 호출되는 메소드로 객체를 통해서 호출
public int sub(int n) { // n:매개변수
int s=0; // 지역변수
for(int i=1; i<=n;i++) {
s+=i;
}
return s;
}
// void는 메소드를 실행 후 결과를 호출한 곳으로 넘길 필요가 없는 경우 사용
public void sub2() {
// 인스턴스 변수는 클래스내의 모든 인스턴스 메소드에서 호출가능하다.
System.out.println(a+" : "+b);
int x = sub(5); // 다른 인스턴스 메소드도 호출 가능.
System.out.println(x);
// 클래스 메소드나 클래스 변수 호출 가능.
System.out.println(c);
demo2();
}
// 클래스 메소드 : 객체 생성과 상관없이 클래스 이름으로 호출하는 메소드
public static void demo() {
// 클래스메소드는 인스터스 변수나 인스턴스 메소드를 직접 호출 불가
// System.out.println(a); // 컴파일 오류
// tt.sub2(); // 컴파일 오류
// 클래스 변수나 클래스 메소드는 호출 가능
System.out.println(c);
// 클래스 메소드에서 객체를 생성하여 인스턴스 변수나 인스턴스메소드 호출
Test1 tt= new Test1();
System.out.println(tt.a+" : "+tt.b);
tt.sub2();
}
public static void demo2() {
System.out.println("demo2 ...");
}
}
class Test7 {
// 접근제어 리턴타입 메소드명(매개변수타입 매개변수명)
// 매개변수는 지역변수로 메소드안에서만 사용 가능
public int sum(int n) {
// 매개변수 : (위에서 변수를 받기 때문에 자료형이 더 커야함
// 1~부터 n까지의 합
int s=0; // 지역변수. 메소드안에서만 사용가능
for(int i=1; i<=n; i++) {
s+=i;
}
return s; // 반환값을 가지고 호출한 곳으로 돌아감.
}
// 짝수인지 판별하는 메소드
public boolean isEven(int n) { // 리턴타입이 있을 경우 리턴을 써야함!
return n%2==0;
}
// 매개변수로 주어진 문자가 소문자이면 대문자로 변환하는 메소드
public char upper(char c) {
return c>='a' && c<='z' ? (char)(c-32) : c;
}
// 매개변수로 주어진 문자가 소문자이면 true, 그렇지 않으면 false
public boolean isLower(char c) {
return c>='a' && c<='z' ;
}
// 두개의 매개변수로 주어진 정수중 큰 수를 반환하는 메소드
public int max(int x, int y) {
return x>y? x : y;
}
// 매개변수로 주어진 구구단 출력. 단 주어진 매개변수가 1~9사이의 수가 아니면 아무것도 출력하지 않음.
// void 리턴 타입 : 메소드를 실행하고 호출한 곳으로 값을 반환 할 필요가 없을 때 사용
// void 리턴 타입인 경우에는 return; 처럼 마지막에 return문을 기술하지만 생략가능
public void gugudan(int dan) {
if(dan<1 || dan>9) {
return; // return을 만나면 메소드는 실행을 멈추고 호출한 곳으로 복귀
}
for(int i=1; i<=9; i++) {
System.out.printf("%d * %d = %2d\n", dan, i, dan*i);
}
return; // void에서는 생략 가능
}
// 점수에 따른 평점 계산
// 95~100ㅣ4.5, 90~94:4.0 ... 59~0 : 0.0
public double grade(int score) {
double s = 0.0;
if(score>=95) s=4.5;
else if(score>=90) s=4.0;
else if(score>=85) s=3.5;
else if(score>=80) s=3.0;
else if(score>=75) s=2.5;
else if(score>=70) s=2.0;
else if(score>=65) s=1.5;
else if(score>=60) s=1.0;
else s = 0.0;
return s;
}
}
원래 하나의 클래스에는 하나의 기능만을 넣어야 한다. 단일책임의 원칙 ( 응집도를 높이기 위함)
이번 포스팅에서는 method의 예를 보기위해 여러개의 기능을 같이 넣었다.
(실제 코딩시에는 이렇게 하면 안된다!!)
public class Ex07_method {
public static void main(String[] args) {
Test7 tt = new Test7();
int result;
result = tt.sum(10);
System.out.println(result);
result = tt.sum(100);
System.out.println(result);
boolean b;
b = tt.isEven(13);
System.out.println(b);
char c;
c = tt.upper('a');
System.out.println(c);
c = tt.upper('9');
System.out.println(c);
result = tt.max(5, 10);
System.out.println(result);
tt.gugudan(7);
double g = tt.grade(85);
System.out.println(g);
}
}
class Test6 {
int a=10;
int b;
// 인스턴스 변수
public void print() {
System.out.println(a+ " : " +b);
// 인스턴스 메소드
}
}
public class Ex06_class {
public static void main(String[] args) {
Test6 t1 = new Test6();
Test6 t2 = new Test6();
t2.b=20;
t1.print();
t2.print();
t2 = t1;
// t1의 주소를 t2에 넣는다.
// t2의 주소를 저장하고 있는 곳이 없으므로 garbage collector의 회수 대상이 되어
// 메모리를 회수한다.
t1.print();
t2.print();
}
}
class Test4 {
// 인스턴스 변수. 객체가 생성되어야 사용가능.
// 객체가 생성될 때 ! 메모리가 할당된다.
int a;
private int b=10;
// 클래스변수. 객체생성과 상관없이 사용가능.
// 클래스가 로딩될 때 메모리 할당
public static int c=100;
// 인스턴스 메소드. 객체가 생성되어야 사용가능.
public void print(){
System.out.println(a+ " : " +b + " : " +c);
}
// 클래스 메소드. 객체 생성과 상관없이 사용 가능.
public static void write(){
// System.out.println(a); 컴파일 오류.
// 클래스 메소드에서는 인스턴스 변수나 인스턴스 메소드를 호출 할 수 없다.
System.out.println(c)
}
}
public class Ex04_class {
public static void main(String[] args) {
System.out.println(Test4.c);
// 클래스 메소드 접근
// "클래스명.메소드명([인수])" 형식으로 접근
Test4.write();
// 인스턴스 변수, 인스턴스 메소드는 객체 생성 후 접근
Test4 tt = new Test();
tt.a=50;
tt.print();
Test4 tt2 = new Test4();
tt2.print();
}
}