Study Web Development

11월 3일

이전으로

자바

6. 클래스와 객체

6-1 클래스의 구조

  1. 새 클래스 InstanceMain01 생성
    • 객체를 생성하면 메모리에 멤버 변수와 멤버 멤서드가 올라가고, 생성자는 올라가지 않음
public class InstanceMain01 { // 클래스의 기본 구조
	// 필드
	int var1; // 멤버 변수
	String var2; // 멤버 변수
	
	// 생성자; 생략 가능
	public InstanceMain01() {}
	
	// 멤버 메서드
	public int sum(int a, int b) { // 메서드에 인자(=파라미터)값을 입력하면
		return a + b; // 정의된 연산을 수행하여 결과값을 반환
	}
	
	public static void main(String[] args) {
		// 객체 선언; 주소가 들어갈 참조 변수를 선언하는 것
		InstanceMain01 me;

		// 객체 생성; 클래스명과 동일한 생성자를 호출해 객체 생성을 유도
		me = new InstanceMain01();

		// 객체의 멤버 변수에 데이터 저장
		me.var1 = 10;
		me.var2 = "가을";

		// 객체의 멤버 변수에 저장된 데이터 읽기
		System.out.println(me.var1 + ", " + me.var2);

		// 객체의 멤버 메서드에 데이터 전달하고 결과값을 변수에 저장(=메서드 동작)
		int result = me.sum(10, 20);
		System.out.println("result = " + result);
	}
}

6-3 멤버 변수와 멤버 메서드

멤버 메서드
  1. 새 클래스 MethodMain01 생성
public class MethodMain01 {
	// 반환하는 데이터가 있는 경우
	public int add(int a, int b){
		return a + b;
	}
	
	// 반환하는 데이터가 없는 경우
	public void print(String str) {
		System.out.println(str);
	}
	
	public static void main(String[] args) { // main 메서드는 반환하는 데이터가 없는 void형 메서드
		// 객체 선언 및 생성
		MethodMain01 method = new MethodMain01(); // 생성자는 명시하지 않아도 호출 가능
		
		// 반환하는 데이터가 있는 메서드 호출
		int result = method.add(5, 8);
		System.out.println("result = " + result);
		
		// 반환하는 데이터가 없는 메서드 호출
		method.print("가을"); // void형 메서드는 데이터가 없으므로 변수에 대입할 수 없음
	}
}
  1. 새 클래스 MethodMain02 생성
public class MethodMain02 {
	// 정수형 데이터를 반환하는 멤버 메서드
	public int signOf(int a) {
		int sign = 0; // 동작 시작
		if(a>0)
			sign = 1;
		else if(a<0)
			sign = -1; //  동작 끝; 초기값을 선언했기 때문에 else 생략 가능
		return sign; // 결과값 반환
	}
	
	public static void main(String[] args) {
		/*
		 * [실습] 입력한 int형 정수가 음수이면 -1을, 0이면 0을, 양수이면 1을 반환하는 signOf 메서드를 작성하시오.
		 * [출력 예시]
		 * 정수 입력 > 5
		 * 결과값은 ?
		 */
		MethodMain02 method = new MethodMain02(); // 메서드는 객체에 포함되어 동작하기 때문에 반드시 객체를 생성해야 사용 가능
		java.util.Scanner input = new java.util.Scanner(System.in);
		System.out.print("정수 입력 > ");
		int result = method.signOf(input.nextInt());
		input.close();
		System.out.println("결과값은 ? " + result);
	}
}
  1. 새 클래스 MethodMain03 생성
public class MethodMain03 {
	// 멤버 변수
	String name;
	int korean;
	int english;
	int math;
	
	// 멤버 메서드
	// 총점 구하기
	public int makeSum() { // 인자가 없는 경우에도 소괄호는 생략할 수 없음
		return korean + english + math; // 멤버 변수들이 같은 객체의 구성원이므로 인자로 받지 않아도 값을 가져다 쓸 수 있음
	}
	// 평균 구하기
	public int makeAverage() {
		return makeSum() / 3; // 같은 객체에 포함된 다른 멤버 메서드를 호출할 수 있음; 인자 없는 메서드를 호출할 경우에도 소괄호는 생략할 수 없음
	}
	
	public static void main(String[] args) {
		MethodMain03 me = new MethodMain03();
		
		me.name = "홍길동";
		me.korean = 98;
		me.english = 97;
		me.math = 96;
		
		System.out.println("이름 : " + me.name);
		System.out.println("국어 : " + me.korean);
		System.out.println("영어 : " + me.english);
		System.out.println("수학 : " + me.math);
		System.out.println("총점 : " + me.makeSum());
		System.out.println("평균 : " + me.makeAverage());
	}
}
  1. 새 클래스 TvMain 생성
class Tv {
	// 멤버 변수(=속성)
	boolean power; // 전원 상태(on/off)
	int channel; // 현재 채널
	
	// 멤버 메서드(=동작)
	public void isPower() {
		power = !power; // power값이 true이면 false로, false이면 true로 토글
	}
	public void channelUp() {
		++channel; // 채널을 1 높임
	}
	public void channelDown() {
		--channel; // 채널을 1 낮춤
	}
}

public class TvMain {
	
	public static void main(String[] args) {
		// 객체 선언 및 생성
		Tv t = new Tv();
		// Tv를 실행
		t.isPower();
		System.out.println("Tv 실행 여부 : " + t.power);
		System.out.println("현재 채널 : " + t.channel);
		// 채널 변경
		t.channel = 7;
		System.out.println("첫 번째 변경된 채널 : " + t.channel);
		// 채널 변경
		t.channelDown();
		System.out.println("두 번째 변경된 채널 : " + t.channel);
		// Tv를 종료
		t.isPower();
		System.out.println("Tv 실행 여부 : " + t.power);
	}
}
  1. 새 클래스 MethodMain04 생성
class Worker {
	/*
	 * [실습] 
	 * Worker
	 * 1) 멤버 변수 : 직원 이름(name), 급여(money), 계좌 잔고(balance)
	 * 2) 멤버 메서드 : work(실행하면 money에 1,000원 누적), deposit(실행하면 money의 돈을 balance로 누적시키고 money는 0으로 처리)
	 * MethodMain04
	 * 1) Worker 객체 생성
	 * 2) 직원의 이름 지정
	 * 3) 10번 일하는데 번 돈이 3,000원일 때마다 계좌에 저축
	 * 4) 직원 이름, 현재 계좌에 입금되지 않고 남아 있는 급여(money), 계좌 잔고(balance)를 출력
	 */
	String name;
	int money, balance;
	
	public void work() {
		money+=1000; // 처음 생성시 0으로 초기화되기 때문에 문제 발생하지 않고 누적됨
	}
	
	public void deposit() {
		balance+=money;
		money=0;
	}
}

public class MethodMain04 {
	public static void main(String[] args) {
		Worker w = new Worker();
		w.name = "너굴";
		for(int i=0;i<10;i++) {
			w.work();
			if(w.money>=3000) { // w.money%3000==0도 가능
				w.deposit();
			}
		}
		System.out.println("이름 : " + w.name);
		System.out.printf("남아 있는 급여 : %,d원\n", w.money);
		System.out.printf("계좌 잔고 : %,d원", w.balance);
	}
}

6-4 패키지와 import

패키지
패키지 사용 및 실행, import문
  1. src 폴더 오른쪽 클릭-New-Package 선택하고 새 패키지 kr.s01.p1 생성 후, kr.s01.p1 오른쪽 클릭하여 새 클래스 PackMain 생성
package kr.s01.p1;

import kr.s01.p2.PackTwo; // 호출하고자 하는 클래스의 패키지를 등록

public class PackMain {
	public static void main(String[] args) {
		// kr.s01.p1.PackOne p1 = new kr.s01.p1.PackOne();
		PackOne p1 = new PackOne(); // 같은 패키지의 클래스는 호출시 패키지명을 생략할 수 있음
		p1.study();
		
		kr.s01.p2.PackTwo p2 = new kr.s01.p2.PackTwo();
		p2.play();
		
		PackTwo p3 = new PackTwo(); // 등록했기 때문에 호출시 패키지명을 생략할 수 있음
		p3.play();
		
	}
}
  1. 새 클래스 PackOne 생성
package kr.s01.p1;

public class PackOne {
	public void study() {
		System.out.println("공부를 열심히 합니다!!");
	}
}
  1. 새 패키지 kr.s01.p2 생성 후 새 클래스 PackTwo 생성
package kr.s01.p2;

public class PackTwo {
	public void play() {
		System.out.println("피아노를 연주합니다!!");
	}
}
  1. 새 패키지 kr.s01.a 생성하고 (default package)에 있던 클래스들을 모두 kr.s01.a로 이동

6-5 접근 제한자

6-7 인자 전달 방식

  1. 새 패키지 kr.s02.method 생성 후 새 클래스 MethodMain01 생성
package kr.s02.method;

public class MethodMain01 {
	// Call by Value
	public int increase(int n) {
		++n;
		return n;
	}
	
	public static void main(String[] args) {
		int var1 = 100;
		
		MethodMain01 me = new MethodMain01();
		int var2 = me.increase(var1);
		
		System.out.println("var1 : " + var1 + ", var2 : " + var2);
	}
}
  1. 새 클래스 MethodMain02 생성
package kr.s02.method;

public class MethodMain02 {
	// Call by Reference
	public void increase(int[] n) { // 배열(객체)의 주소를 n에 전달
		for(int i=0;i<n.length;i++) { // 주소가 저장된 n을 통해 배열에 접근; n과 ref1은 동일한 배열을 가리킴
			n[i]++;
		}
	}
	
	public static void main(String[] args) {
		int[] ref1 = {100, 200, 300}; // 배열의 선언, 생성, 초기화
		for(int i=0;i<ref1.length;i++) { // 메서드 호출 전
			System.out.println("ref1[" + i + "] : " + ref1[i]);
		}
		MethodMain02 me = new MethodMain02(); // 객체의 선언, 생성
		me.increase(ref1); // 메서드 호출
		for(int i=0;i<ref1.length;i++) { // 메서드 호출 후
			System.out.println("ref1[" + i + "] : " + ref1[i]);
		}
	}
}
  1. 새 클래스 MethodMain03 생성
package kr.s02.method;

public class MethodMain03 {
	// Variable Arguments
	public void argTest(int ... n) { // 자료형을 명시하고 ... 후에 인자를 명시하면 가변 인자가 됨
		for(int i=0;i<n.length;i++) {
			System.out.println("n[" + i + "] : " + n[i]);
		}
		System.out.println("========");
	}
	
	public static void main(String[] args) {
		MethodMain03 me = new MethodMain03();
		me.argTest(); // 인자를 입력하지 않은 경우, 길이 0인 빈 배열이 생성되어 for문은 동작하지 않음
		me.argTest(10); // 10이 n에 직접 전달되는 것이 아니라, n이 가리키는 길이 1인 배열의 요소가 됨
		me.argTest(20, 30);
		me.argTest(40, 50, 60);
	}
}
  1. 새 클래스 MethodMain04 생성
package kr.s02.method;

import java.util.Scanner;
/*
 * [실습] 
 * Account
 * 1) 멤버 변수 : 계좌 번호(account_num), 예금주(name), 잔고(balance)
 * 2) 멤버 메서드 : 
 * 1. 예금하기(deposit): balance 값 누적 후, 입금이 완료되었습니다. 출력
 * 2. 출금하기(withdraw): balance 값 차감 후, 출금이 완료되었습니다. 출력
 * 3. 계좌정보(printAccount): 계좌 번호, 예금주, 잔고 출력
 * MethodMain04
 * 1) Account 생성
 * 2) 계좌 기본 정보 입력: 계좌 번호, 예금주, 잔고
 * 3) 계좌 정보 출력
 * 4) 입금하기
 * 5) 계좌 정보 출력
 * 6) 출금하기
 * 7) 계좌 정보 출력
 */
class Account {
	String account_num, name;
	int balance;
	
	public void deposit(int n) {
		balance+=n;
		System.out.println("입금이 완료되었습니다.");
	}
	public void withdraw(int n) {
		balance-=n;
		System.out.println("출금이 완료되었습니다.");
	}
	public void printAccount() {
		System.out.println("====계좌 정보====");
		System.out.println("계좌 번호 : "+account_num);
		System.out.println("예금주 : "+name);
		System.out.printf("잔고 : %,d원\n", balance);
	}
}

public class MethodMain04 {
	public static void main(String[] args) {
		Account bank=new Account();
		Scanner input=new Scanner(System.in);
		
		System.out.println("계좌 기본 정보를 입력하세요.");
		System.out.print("계좌번호 > ");
		bank.account_num=input.nextLine(); // 한 줄 전체를 입력받는 메서드
		System.out.print("예금주 > ");
		bank.name=input.next(); // 공백 전까지를 입력받는 메서드
		System.out.print("잔고 > ");
		bank.balance=input.nextInt();
		/*
		bank.printAccount();

		System.out.println("====입금====");
		System.out.print("입금할 금액을 입력하세요 > ");
		bank.deposit(input.nextInt());
		bank.printAccount();
		
		System.out.println("====출금====");
		System.out.print("출금할 금액을 입력하세요 > ");
		bank.withdraw(input.nextInt());
		bank.printAccount();
		*/
		while(true) { // 메뉴 만들기; 기본 정보는 while문 밖에서 먼저 입력해야 함
			System.out.println("========");
			System.out.println("1. 예금|2. 출금|3. 잔고|4. 종료");
			System.out.println("========");
			
			System.out.print("메뉴 선택 > ");
			int num=input.nextInt();
			if(num==1) {
				System.out.print("예금액 > ");
				bank.deposit(input.nextInt());
			}
			else if(num==2) {
				System.out.print("출금액 > ");
				bank.withdraw(input.nextInt());
			}
			else if(num==3) {
				bank.printAccount();
			}
			else if(num==4) {
				System.out.println("프로그램 종료");
				break;
			}
			else {
				System.out.println("메뉴를 잘못 선택하셨습니다.");
			}
		}
		input.close();
	}
}

과제

  1. 프로젝트 ch03-operation에 새 클래스 IfMain07 생성
import java.util.Scanner;
public class IfMain07 {
	public static void main(String[] args) {
		/*
		 * [실습]
		 * 생년월일을 입력하고 만 나이를 출력하는 프로그램을 작성하시오.
		 * 만 나이 = (현재 연도 - 생년) - (생일이 지났으면 0, 생일이 지나지 않았으면 1)
		 * 
		 * [출력 예시]
		 * 연도 입력 : 2001
		 * 월 입력 : 10
		 * 일 입력 : 20
		 * 만 나이는 ?
		 */
		int thisYear = 2021;
		int thisMonth = 11;
		int thisDate = 3;
		
		Scanner input = new Scanner(System.in);
		System.out.print("연도 : ");
		int year = input.nextInt();
		System.out.print("월 : ");
		int month = input.nextInt();
		System.out.print("일 : ");
		int date = input.nextInt();
		
		// 나이 구하기
		int age = thisYear - year;
		
		// 만 나이 구하기
		if(thisMonth < month) { // 생일 월이 오지 않음
			age--;
		}
		else if(thisMonth == month) {
			if(thisDate < date) { // 생일 월이지만 생일 일이 오지 않음
				age--;
			} // else는 생일 월이고 생일 일이 지난 경우로 별도의 연산 필요 없음
		} // else는 생일 월이 지난 경우로 별도의 연산 필요 없음
		System.out.printf("만 나이는 %d\n", age);
	}
}

다음으로