본문 바로가기
국비 교육/백엔드(Java, Spring)

[자바] 클래스 Class

by 육츠 2024. 1. 22.
Contents 접기

Method  : 클래스를 구성하는 요소.

메소드 작성

[접근지정자] [지정자] [반환형] [메소드 이름] ([매개변수]) {
    메소드 몸체;
    [return 데이터;]
}

 

메소드 호출

add(10, 20);   ---> argument
public int add(int x, int y) ---> parameter

public class MethodTest01 {

	public static void main(String[] args) {
		int result  = add(12,34);
		// 12(아규먼트) -> a, 34 -> b
		// int result 아래 메소드는 지역 변수이기 때문에 메소드가 끝나면 사용이 종료된다.
		// 때문에 같은 이름으로 main 에서 선언해도 된다.
		
		System.out.println(result);
		Math.random(); // static
		
		// 예상 모습 추측
//		public class Math{
//			public static double random() 
//	        return double;
//		}
		
	} // 중괄호가 닫히고 나서 메소드가 선언된다.
	
	
	// 메소드의 선언과 정의
	// int a, int b : 파라미터 
	
	
	static int add(int a, int b){
		int result = a + b;
		return result;
	}

}
코드 역할
add(12,34); 12 -> a, 34 -> b  --> 12 = argument (전달 인자)
int a, int b  파라미터 (매개 변수)
public  생략 가능
static 생략 불가
public static void main(String[] args) {
int result  = add(12,34);

static int add(int a, int b){
    int result = a + b;
    return result;
}
int result

= 메소드의 사용된 변수는 지역 변수이기 때문에 메소드가 끝나면 사용이 종료된다.
때문에 같은 변수 이름으로 main 에서 선언이 가능하다.
(아래 메소드의 변수와 main 변수는 이름만 같은 변수이다.)

 static 에서는 non-static 호출 불가!  // static은 가급적 많이 사용하지 않아야 한다.

 

call by value vs call by reference

- call by value

원본의 값이 변경되지 않는다. 값에 의한 호출  = 원본에 접근할 수 없다.

public class MethodTest02 {

	public static void main(String[] args) {
		int x =10 , y = 20;
		
		System.out.println(x +", " + y); //10, 20
		
		exchange(x,y);// call by value : 값에 의한 호출  = 원본에 접근할 수 없다.
		// int temp = exchange(x,y);// 반환 받고 싶을때 대입한다.
		
		System.out.println(x +", " + y); // 10, 20
		
	} // main 까지 밖에 Life Cycle
	
	public static void exchange(int x, int y){ //교환
		int temp;
		temp = x;
		x = y;
		y = temp;
//		System.out.println(x +", " + y); // 20, 10
		
	} // exchange 까지 밖에 Life Cycle
	
//	public static int exchange(int x, int y){ //교환
//		int temp;
//		temp = x;
//		x = y;
//		y = temp;
//		System.out.println(x +", " + y); // 20, 10
//		
//		return 0; // int로 반환 받겠다고 했으니까 반환값이 필요한 것
//		
//	} // exchange 까지 밖에 Life Cycle
//	
	

}
코드 의미
public static void main(String[] args) {
    exchange(x,y);
    }

    public static void exchange(int[] arr){ //교환
        int temp;
        temp = x;
        x = y;
        y = temp;
   }
void로 반환값 설정 ==> 반환값 필요없음.

exchange(x,y); ==>  대입 필요 없음.
public static void main(String[] args) {
    int temp = exchange(x,y);
    }

    public static int exchange(int x, int y){ //교환
        int temp;
        temp = x;
        x = y;
        y = temp;
       
         return 0; (임의 값)
         } 
int로 반환값 설정 ==> int 타입의 반환값 필요.

 int temp = exchange(x,y); ==>  대입 필요.

 

- call by reference

원본의 값이 변경된다. 변수의 주소를 전달하는 방식.

// call by refernce

public class MethodTest03 {

	public static void main(String[] args) {
		int[] arr = {10,20}; // 무엇으로 선언을 했는지 중요
		
		System.out.println(arr[0] +", " + arr[1]); //10, 20
		
		// exchange(arr);
		int[] temp = exchange(arr); // 반환과 동일하게 받아야함.
		
		System.out.println(arr[0] +", " + arr[1]); //20, 10 : 원본이 변경된다
		
	} // main 까지 밖에 Life Cycle
	
//	public static void exchange(int[] arr){ //교환
//		int temp;
//		temp = arr[0];
//		arr[0] = arr[1];
//		arr[1] = temp;
//	}
	
	public static int[] exchange(int[] arr){ //교환
		int temp;
		temp = arr[0];
		arr[0] = arr[1];
		arr[1] = temp;
		
		return arr;
	} 

}
코드 의미
public static void main(String[] args) {
    exchange(arr);
    }

    public static void exchange(int[] arr){ //교환
        int temp;
        temp = arr[0];
        arr[0] = arr[1];
        arr[1] = temp;
   }
void로 반환값 설정 ==> 반환값 필요없음.

exchange(x,y); ==>  대입 필요 없음.
public static void main(String[] args) {
    int[] temp = exchange(arr); 
    }

    public static int[] exchange(int[] arr){ //교환
        int temp;
        temp = arr[0];
        arr[0] = arr[1];
        arr[1] = temp;

        return arr;
     
*** 반환과 동일하게 받아야 한다.
배열로 생성 -> 배열로 받는다

int[] arr = {10,20}; 

int[] temp = exchange(arr);

public static int[] exchange(int[] arr){ 

 

class

구조

접근지정자 class 클래스 이름{
    생성자
    멤버 변수
    메소드
}

 

객체 생성 및 사용방법

선언 및 초기화

[클래스명] [객체 변수명] = new [클래스명]();

필드(변수) 호출

[객체 변수명].[필드명= 멤버변수명];

메소드 호출

[객체 변수명].[메소드명]([인수]);

 

생성

사용자 정의 클래스 = VO (Value Object)

package mypackage;

// 사용자 정의 클래스 = VO (Value Object)
// 객체 생성 ->  new 를 사용
public class Score {
	// 아이디, 이름, 국어, 영어, 수학, 평균
	
	// 사용자 정의 타입
	String id; // 멤버 변수 = 인스턴스 변수
	String name;
	
	int kor;
	int mat;
	int eng;
	double avg;
	// = default = 같은 패키지
	
	public void calcavg() {
		avg = (kor + mat + eng) / 3;
	}
	
	// v3: 출력문을 위한 메소드를 생성하시오.
	// static을 가지면 우리멤버가 아니다.
	public void output() { 
		System.out.printf("%s : %.2f\n", name, avg);
	}

	
	// 우리 멤버 = 서로 접근 할 수 있다.
	// 머리가 같은 멤버 변수
	
	// 설계도이기 때문에 돌릴 수 없다.
	
	
}
사용자 정의 클래스 = VO (Value Object) 사용자 정의 타입 (멤버 변수 = 인스턴스 변수) 
public class Score  public 
= 모든 클래스 및 외부 패키지의 클래스에서 접근

우리 멤버
= 머리가 같은 멤버 변수
= 서로 접근 할 수 있다.
String id; 
String name;

int kor;
int mat;
int eng;
double avg;
default 
= 같은 패키지의 클래스에서만  접근

 

Score 클래스를 생성하는 방식

Score(클래스명) 변수명 = new Score();  ==> non - static 은 반드시 new(참조 변수)를 사용해야함.

package mypackage;
// __Test = main을 가지고 있다

public class ScoreTest {

	public static void main(String[] args) {
		Score s1 = new Score(); // 메모리에 올림
		// ㅁ -> ㅁ(id)ㅁ(name)ㅁ(kor)ㅁ(mat)ㅁ(eng)ㅁ(avg)

		s1.id = "123"; // 직접 접근 ==> 객체지향에서는 옳지 않음 (? 정보은닉 특징)
		s1.name = "홍길동";
		s1.kor = 67;
		s1.mat = 60;
		s1.eng = 97;

		s1.calcavg(); // 내부적으로 계산

		//System.out.println(s1.name + " : " + s1.avg); 
		// output(s1);
		s1.output();
		// s2 객체를 임의로 생성하여 결과 출력

		Score s2 = new Score(); // 메모리에 올림
		s2.id = "124";
		s2.name = "전우치";
		s2.kor = 65;
		s2.mat = 68;
		s2.eng = 91;

		s2.calcavg(); // 내부적으로 계산

		// System.out.println(s2.name + " : " + s2.avg); 
		// output(s2);
		s2.output();

	}
	
	// v2: 출력문을 위한 메소드를 생성하시오.
	public static void output(Score s) { // Score 타입이다.
		System.out.printf("%s : %.2f\n", s.name, s.avg);
	}

}
코드 의미
v1: System.out.println(s1.name + " : " + s1.avg);  객체 생성한 Score 타입 이용해서 출력
v2: output(s1);
public static void output(Score s) { // Score 타입이다.
    System.out.printf("%s : %.2f\n", s.name, s.avg);
}
출력문을 위한 메소드를 생성하여 main() 에서 사용
v3: s1.output();
public void output() { 
    System.out.printf("%s : %.2f\n", name, avg);
}
Score 객체 안에 출력문을 위한 메소드를 생성하여 main에서 사용.(static을 가지면 우리멤버가 아니다.)

** 우리 멤버 = 서로 접근 할 수 있다.

 

접근지정자 : private

같은 클래스에서만 접근 가능하다 = 외부에서의 접근이 안된다 (정보 은닉을 위해)

package mypakage2;

// 사용자 정의 클래스 = VO (Value Object)
// 객체 생성 ->  new 를 사용
public class Score {
	
	private String id;  
	private String name;  
	private int kor;
	private int mat;
	private int eng;
	private double avg;
	
	
	// setter : 우리 멤버 변수의 값을 변경하는 용도
	// public void setId(변수명)(String i) { id = i; } 
	// 로직은 아님. private 이 있다면 무조건!!
	public void setId(String i) {
		id = i;
	}
	public void setName(String n) {
		name = n;
	}
	public void setKor(int k) {
		kor = k;
	}
	public void setMat(int m) { // 외부에서 전달받은 데이터
		mat = m;
	}
	public void setEng(int e) {
		eng = e;
	}
	
	
	// 계산에 의해 만들어지는 데이터는 setter 를 만들 필요 없음
	public void calcavg() {
		avg = (kor + mat + eng) / 3.0;
	}
	
	public void output() { 
		System.out.printf("%s : %.2f\n", name, avg);
	}
	
	
}

 

필요한 문법 의미
gatter

public String getName() {
    return this.name;
  }

- 값을 조회하고자 할때 이용한다.
- 이름에 무조건  'get' 이라는 글자가 들어가야한다.
- 매개 변수 값을 넣지 않는다.

setter  (private 이 있다면 무조건)

public void setId(String i) {
    id = i;
}
- 우리 멤버 변수의 값을 변경하는 용도이다.
- 이름에 무조건  'set' 이라는 글자가 들어가야한다.
- 계산에 의해 만들어지는 데이터는 setter를 만들 필요 없다

 

package mypakage2;
import mypakage2.Score;
public class ScoreTest {

	public static void main(String[] args) {

		Score s1 = new Score(); // 접근 불가 상태이기 때문에 보이지 않음

		// s1.id = "123"; // 직접 접근 불가
		s1.setId("123");
		s1.setName("홍길동");
		s1.setKor(76);
		s1.setMat(66);
		s1.setEng(80);
		
        ....

	}

setter 를 쓰게 되면 s1.id = "123"; 과 같이 직접 접근 불가능해지기 때문에 public 을 통해 값을 넣는다. 

 

[Q] 사용자로 부터 아래 메뉴중 하나를 입력 받아 처리하는 메소드를 작성하시오.

<실행>

1. 덧셈
2. 뺄셈
3. 곱셈
4. 나눗셈
0. 종료
--------------
> 선택: 1

### 덧셈 ###
값 1: 10
값 2: 20
결과: 30
...

import java.util.Scanner;

public class Exam29 {

	public static void main(String[] args) {
		int menu;
		double a,b;
		double result =0;

		Scanner scanner = new Scanner(System.in);

		while (true) {
			System.out.println("메뉴 선택");
			System.out.println("1. 덧셈");
			System.out.println("2. 뺄셈");
			System.out.println("3. 곱셈");
			System.out.println("4. 나눗셈");
			System.out.println("0. 종료");
			System.out.println("---------");
			System.out.print("> ");
			menu = scanner.nextInt();

			// 앞에 if를 놓으면 안 해도 되겠구나 안에 하나씩 안 넣어도 되겠구나
			if (menu ==0) {
				// menu.equals("0")
				System.out.println("종료.");
				System.exit(0); 
				// return : 메서드 내에서 자신을 호출한 곳으로 되돌아감. = 프로그램 종료
			}


			System.out.print("값 1: ");
			a = scanner.nextDouble();
			System.out.print("값 2: ");
			b = scanner.nextDouble();


			switch(menu) {
			case 1: { System.out.println("### 덧셈 ###"); 
			result = add(a,b); 
			break;
			}

			case 2 : { System.out.println("### 뺄셈 ###"); 
			result = substract(a,b); 
			break;
			}

			case 3 : { System.out.println("### 곱셈 ###"); 
			result = multiply(a,b); 
			break;
			}

			case 4 : { System.out.println("### 나눗셈 ###"); 
			result = divide(a,b); 
			break;
			}
			default : {
				System.out.println("## 메뉴 다시 선택");
				scanner.nextLine();
				continue;
			}

			}

			System.out.printf("결과: %.2f" ,result);
			System.out.println();


		}
	}
	public static double add (double a, double b) {
		return  a + b;
	}

	public static double substract (double a, double b) {
		return a - b;
	}

	public static double multiply (double a, double b) {
		return a * b;
	}

	public static double divide (double a, double b) {
		return a / b;
	}


}

 

[Q] Bank Account

VO 클래스를 설계하시오.

1) BankAccount
- 계좌주(name), 계좌번호(no), 잔고(balance),   --- > 명사
- 입금(deposit), 출금(withdraw), 출력(output)     --- > 동사

2) BankAccountTest(main) 

 

1) 클래스

여기서 this 란  현재 객체의 name 인스턴스 변수를 반환한다. 우리멤버만  this 가능 

package mypakage3;

public class BankAccount {
	private String name;  
	private String no;  
	private int balance;
	
	public void setName(String na) {
		name = na;
		// this.name = name;
	}
	public void setNo(String n) {
		no = n;
		// this.no = no;
	}
	public void setBalance(int b) {
	 	balance = b;
	 	// this.balance = balance;
	 }
	
	
	public String getName(){
		return this.name;
	  } // 우리멤버만  this 가능
	
	public String getNo(){
		return this.no;
	} // 우리멤버만 this 가능 (안붙여도  알아서 붙음)
	
	public int getbalance(){
		return balance;
	} 
	
	
	public void deposit(int money) {
		balance += money;
	}
	public int withdraw(int money) {
		if(balance < money) return 0;
		balance -= money;
		return money;
	}
	public void output() {
		System.out.printf("%s(%s) - %,d원\n", name, no, balance);
	}
	
}

 

2) main

package mypakage3;

public class BankAccountTest {

	public static void main(String[] args) {
		BankAccount a1 = new BankAccount(); 
		// name, no, balance =  null, null, 0 이 들어있음
		BankAccount b1 = new BankAccount(); 
		// b1.setName(null);
		// b1.setBalance(0);
        
        // 값 변환
		a1.setName("전우치");
		a1.setNo("123");
		
		a1.deposit(15000);
		a1.output();
		
		a1.withdraw(10000);
		a1.output();
		
		int result = a1.withdraw(100000);
		if(result == 0) System.out.println("잔고 부족");
		a1.output();
		
		
		// getter 쓰는 법 (gpt)
		// String name = a1.getName();
        // System.out.println("이름: " + name);

	}

}

전우치(123) - 15,000원
전우치(123) - 5,000원

잔고 부족

전우치(123) - 5,000원