본문 바로가기
들은 강의

[생활코딩 자바1] - 4. 나의 앱 만들기

by hotdog7778 2023. 6. 6.

쉽게 배우는 자바1[생활코딩] - 공부 기록

해당 강의는 https://www.boostcourse.org/cs126 에서 무료로 수강 할 수 있다.


4. 나의 앱 만들기

위 도식대로 프로그램을 구현한 후에,

 - 변수 도입

 - 입력값 도입

 - 조건문

 - 배열

 - 반복문

 - 메소드

 - 클래스

 - 인스턴스

개념들을 활용해서 프로그램을 업그레이드 해보자.

 

1. 목적에 맞게 프로그램을 작성.

public class AccountingApp {

	public static void main(String[] args) {
    
	System.out.println("Value of supply : " + 10000.0);
        System.out.println("VAT : " + (10000.0 * 0.1));
        System.out.println("Total : " + (10000.0 + (10000.0 * 0.1)));
        System.out.println("Expense : " + (10000.0 * 0.3));
        System.out.println("Income : " + (10000.0 - (10000.0 * 0.3)));
        System.out.println("Dividend 1 : " + (10000.0 - (10000.0 * 0.3)) * 0.5); // 1번 배당
        System.out.println("Dividend 2 : " + (10000.0 - (10000.0 * 0.3)) * 0.3); // 2번 배당
        System.out.println("Dividend 3 : " + (10000.0 - (10000.0 * 0.3)) * 0.2); // 3번 배당

	}

}

실행 결과는.

Value of supply : 10000.0
VAT : 1000.0
Total : 11000.0
Expense : 3000.0
Income : 7000.0
Dividend 1 : 3500.0
Dividend 2 : 2100.0
Dividend 3 : 1400.0

 

2. 변수, 리팩토링 활용해서 코드를 바꿔보자.

public class AccountingApp {

	public static void main(String[] args) {
		
		double valueOfSupply = 12345.0;
		double vatRate = 0.1;
		double expenseRate = 0.3;
		double vat = valueOfSupply * vatRate;
		double total = valueOfSupply + vat;
		double expense = valueOfSupply * expenseRate;
		double income = valueOfSupply - expense;
		double dividend1 = (income) * 0.5;
		double dividend2 = (income) * 0.3;
		double dividend3 = (income) * 0.2;
		
		System.out.println("Value of supply : "+valueOfSupply);
		System.out.println("VAT : "+ vat );
		System.out.println("Total : "+ total );
		System.out.println("Expense : "+expense );
		System.out.println("Income : "+ income );
		System.out.println("Dividend 1 : "+ dividend1 ); // 1번 배당
		System.out.println("Dividend 2 : "+ dividend2 ); // 2번 배당
		System.out.println("Dividend 3 : "+ dividend3 ); // 3번 배당
	}

}

이렇게 프로그램의 기능은 바꾸지 않으면서 이해하기 쉽게 바꾸는 과정을 리팩토링이라고 함.

※ 이클립스에서 특정 값을 지역 변수로 바꾸기 위해 Extract Local Variable 기능을 이용할 수 있습니다. (단축키 : ALT+Shift+L)

 

3. 아규먼트를 받아서 자동적으로 공급가를 바꿀수 있는 프로그램으로 만들기.

public class AccountingApp {

	public static void main(String[] args) {
		
		double valueOfSupply = Double.parseDouble(args[0]); // string인 args를 double로 바꿔야 한다. 
		double vatRate = 0.1;
		double expenseRate = 0.3;
		double vat = valueOfSupply * vatRate;
		double total = valueOfSupply + vat;
		double expense = valueOfSupply * expenseRate;
		double income = valueOfSupply - expense;
		double dividend1 = (income) * 0.5;
		double dividend2 = (income) * 0.3;
		double dividend3 = (income) * 0.2;
		
		System.out.println("Value of supply : "+valueOfSupply);
		System.out.println("VAT : "+ vat );
		System.out.println("Total : "+ total );
		System.out.println("Expense : "+expense );
		System.out.println("Income : "+ income );
		System.out.println("Dividend 1 : "+ dividend1 ); // 1번 배당
		System.out.println("Dividend 2 : "+ dividend2 ); // 2번 배당
		System.out.println("Dividend 3 : "+ dividend3 ); // 3번 배당
	}

}
 

이렇게 되면 공급가인 valueOfSupply 를 프로그램 실행전에 아규먼트로 받을 수 있다. EX) 만원, 이만원, 삼만원 등

 

4. 조건문 if를 활용해서 프로그램 바꿔보기.

수익(income)이 1만원이 넘을 경우에만 동업자들에게 기존의 배당률대로 수익을 배당하고,

수익이 1만원 이하일 경우에는 1번 동업자에게만 모든 수익을 배당하도록!

public class AccountingIFApp {

	public static void main(String[] args) {
		
		double valueOfSupply = Double.parseDouble(args[0]); // string인 args를 double로 바꿔야 한다. 
		double vatRate = 0.1;
		double expenseRate = 0.3;
		double vat = valueOfSupply * vatRate;
		double total = valueOfSupply + vat;
		double expense = valueOfSupply * expenseRate;
		double income = valueOfSupply - expense;
		
		double dividend1;
		double dividend2;
		double dividend3;
		
		//income이 만원보다 적으면 그냥 1번이 다가져가도록 IF문 사용
		if(income > 10000.0) {
			dividend1 = (income) * 0.5;
			dividend2 = (income) * 0.3;
			dividend3 = (income) * 0.2;
		} else {
			dividend1 = (income) * 1.0;
			dividend2 = (income) * 0.0;
			dividend3 = (income) * 0.0;	
		}
		
		System.out.println("Value of supply : "+valueOfSupply);
		System.out.println("VAT : "+ vat );
		System.out.println("Total : "+ total );
		System.out.println("Expense : "+expense );
		System.out.println("Income : "+ income );
		System.out.println("Dividend 1 : "+ dividend1 ); // 1번 배당
		System.out.println("Dividend 2 : "+ dividend2 ); // 2번 배당
		System.out.println("Dividend 3 : "+ dividend3 ); // 3번 배당
	}

}

 

5. 배열을 사용해서 프로그램을 바꿔보기

1번,2번,3번 배당에 적용되는 배당률이 각각 다른데, 이 수치들을 배열에 넣어서 사용해보자.

 

main 메소드의 파라미터로 있던 args 는 여러개의 문자열을 담을 수 있는 배열 이다. 

각각의 배당률을 배열을 사용해서 변수화 했다.

public class AccountingArrayApp {

	public static void main(String[] args) {
		
		double valueOfSupply = Double.parseDouble(args[0]); // string인 args를 double로 바꿔야 한다. 
		double vatRate = 0.1;
		double expenseRate = 0.3;
		double vat = valueOfSupply * vatRate;
		double total = valueOfSupply + vat;
		double expense = valueOfSupply * expenseRate;
		double income = valueOfSupply - expense;
		
		//배열을 만들어보자
		double[] dividendRates = new double[3]; //더블형 배열
		dividendRates[0] = 0.5;
		dividendRates[1] = 0.3;
		dividendRates[2] = 0.2;
		
		double dividend1 = income * dividendRates[0];
		double dividend2 = income * dividendRates[1];
		double dividend3 = income * dividendRates[2];
		
		System.out.println("Value of supply : "+valueOfSupply);
		System.out.println("VAT : "+ vat );
		System.out.println("Total : "+ total );
		System.out.println("Expense : "+expense );
		System.out.println("Income : "+ income );
		System.out.println("Dividend 1 : "+ dividend1 ); // 1번 배당
		System.out.println("Dividend 2 : "+ dividend2 ); // 2번 배당
		System.out.println("Dividend 3 : "+ dividend3 ); // 3번 배당
	}

}

 

5. 반복문 while을 사용해서 프로그램 바꿔보기

배열과 반복문은 시너지를 낼 수 있다.

 

dividendRates 배열의 요소 수는 배당률을 가지는 동업자의 수와 같다. 라는 것을 이용해서

동업자의 수만큼 배당률을 확인할 수 있도록 반복문을 만든다.

public class AccountingArrayLoopApp {

	public static void main(String[] args) {
		
		double valueOfSupply = Double.parseDouble(args[0]); // string인 args를 double로 바꿔야 한다. 
		double vatRate = 0.1;
		double expenseRate = 0.3;
		double vat = valueOfSupply * vatRate;
		double total = valueOfSupply + vat;
		double expense = valueOfSupply * expenseRate;
		double income = valueOfSupply - expense;
		
		System.out.println("Value of supply : "+valueOfSupply);
		System.out.println("VAT : "+ vat );
		System.out.println("Total : "+ total );
		System.out.println("Expense : "+expense );
		System.out.println("Income : "+ income );
		
		//배열을 만들어보자
		double[] dividendRates = new double[3]; //더블형 배열
		dividendRates[0] = 0.5;
		dividendRates[1] = 0.3;
		dividendRates[2] = 0.2;
		
		//3번 실행되는 반복문을 만들어보자
		int i = 0;
		while(i < dividendRates.length) {
			System.out.println("Dividend 1 : "+ income * dividendRates[i] );
			i = i + 1;
		}
	}	
}

dividendRates.length 를 사용해서 배열 요소의 수를 확인

 

6. 메소드를 사용해서 만든 코드를 정리해보자

메소드는 C에서 배운 함수와 비슷하다.

 

메소드는 클래스의 동작을 나타내는 함수.

내가 만든 프로그램을 메소드를 사용해서 정리.

 

핵심 단어 : 

  • 메소드(method) : 서로 연관된 코드들을 그룹핑해서 이름을 붙인 상자
  • 필드(Field) : 자바에서는 전역변수를 필드라고도 함
  • 지역 변수(Local Variable)

이클립스 기능을 사용해서 vat를 메소드로 추출하는 방법

double vat = valueOfSupply * vatRate;

위의 vat를 계산하는 코드에서 = 뒤의 값 부분을 드래그 한후에 우클릭,

Refactor - Extract Method를 클릭

getVAT로 메소드의 이름을 지정하고 public 옵션을 선택한 후 OK

 

public class AccountingMethodApp {
 
    public static void main(String[] args) {
 
        ...

        double vat = getVAT(valueOfSupply, vatRate);

        ...
    }

	public static double getVAT(double valueOfSupply, double vatRate) {
		return valueOfSupply * vatRate;
	}
 
}

그러면, 이런식으로 getVAT 메소드가 생성되고, 본문에서는 getVAT메소드로 값을 가져올 수 있음.

main 메소드에 변수 선언되어 있는 것들이 지역변수.

 

getVAT 메소드가 이러한 지역변수를 사용 하려면

getVAT(double valueOfSupply, double vatRate)

이런식으로 파라미터를 받아야 하는데 조금 지저분해서 없애보려 한다.

 

먼저, main 메소드 밖으로 빼는 것을 통해 지역변수를 전역변수로 바꿔준다.

이 과정에서 이클립스 기능을 사용 할 수도 있다.

 - getVAT의 아규먼트로 주고 있는 valueOfSupply와 vatRate 변수에서 Refactor - Convert Local Variable to Filed를 클릭, 변수 이름을 지정하고 public 변수로 OK

 

전역변수로 바뀌면 이런모습

valueOfSupply는 클래스 어디에서도 접근할 수 있는 변수가 되었고, 변수의 값은 main 메소드 안에서 할당하고 있다.

public class AccountingMethodApp {
 
    public static double valueOfSupply;

	public static void main(String[] args) {
 
        valueOfSupply = 10000.0;
        double vatRate = 0.1;

        ...
}

 

이제 원하던 대로 getVAT의 파라미터를 없애면

public class AccountingMethodApp {
 
    public static double valueOfSupply;
	public static double vatRate;

	public static void main(String[] args) {
 
        ...

        double vat = getVAT();

       ...
 
    }

	public static double getVAT() {
		return valueOfSupply * vatRate;
	}
 
}

 

나머지 변수들도 메소드화 해보자.

public class AccountingMethodApp {
	public static double valueOfSupply; //전역변수
	public static double vatRate;
	public static double expenseRate;
	public static void main(String[] args) {
		valueOfSupply = 10000;
		vatRate = 0.1;
		expenseRate = 0.3;
		print();
	}

	public static void print() {
		System.out.println("Value of supply : "+valueOfSupply);
		System.out.println("VAT : "+ getVAT() );
		System.out.println("Total : "+ getTotal() );
		System.out.println("Expense : "+getExpense() );
		System.out.println("Income : "+ getIncome() );
		System.out.println("Dividend 1 : "+ getDiviend1() ); // 1번 배당
		System.out.println("Dividend 2 : "+ getDiviend2() ); // 2번 배당
		System.out.println("Dividend 3 : "+ getDiviend3() ); // 3번 배당
	}

	public static double getDiviend3() {
		return getIncome() * 0.2;
	}

	public static double getDiviend2() {
		return getIncome() * 0.3;
	}

	public static double getDiviend1() {
		return getIncome() * 0.5;
	}

	public static double getIncome() {
		return valueOfSupply - getExpense();
	}

	public static double getExpense() {
		return valueOfSupply * expenseRate;
	}

	public static double getTotal() {
		return valueOfSupply + getVAT();
	}
	
	// 메소드를 만드는 코드
	public static double getVAT() {
		return valueOfSupply * vatRate;
	}

}

 

 

7. 이번에는 클래스로 코드를 정리해보자.

 

통째로 클래스로 격리시켜서 정리정돈하는 방법

 

객체는 클래스라고도 표현하는데, 클래스는 서로 연관된 변수와 메소드를 그룹핑 한것이다.

 

뼈대 = 메소드, 클래스 >> 프로그램의 구조에 영향

 

※ 이클립스의 아웃라인은

클래스안에 소속된 여러가지 멤버들. 멤버라는건 클래스 소속의 변수, 메소드 들이고. 그러한 멤버들을 보여줌.

 

class Accounting{
		public static double valueOfSupply; //전역변수
		public static double vatRate;
		public static double expenseRate;
		public static void print() {
			System.out.println("Value of supply : "+valueOfSupply);
			System.out.println("VAT : "+ getVAT() );
			System.out.println("Total : "+ getTotal() );
			System.out.println("Expense : "+getExpense() );
			System.out.println("Income : "+ getIncome() );
			System.out.println("Dividend 1 : "+ getDiviend1() ); // 1번 배당
			System.out.println("Dividend 2 : "+ getDiviend2() ); // 2번 배당
			System.out.println("Dividend 3 : "+ getDiviend3() ); // 3번 배당
		}
		public static double getDiviend3() {
			return getIncome() * 0.2;
		}
		public static double getDiviend2() {
			return getIncome() * 0.3;
		}
		public static double getDiviend1() {
			return getIncome() * 0.5;
		}
		public static double getIncome() {
			return valueOfSupply - getExpense();
		}
		public static double getExpense() {
			return valueOfSupply * expenseRate;
		}
		public static double getTotal() {
			return valueOfSupply + getVAT();
		}
		public static double getVAT() {
			return valueOfSupply * vatRate;
		}
}

public class AccountingClassApp {
	
	public static void main(String[] args) {
		Accounting.valueOfSupply = 10000;
		Accounting.vatRate = 0.1;
		Accounting.expenseRate = 0.3;
		Accounting.print();
	}
}

Accounting 클래스에 변수와 메소드들을 정의해 놓고, 

AccountingClassApp 클래스에 내가 동작시키고 싶은 기능들을 구현해 놓는다!

 

클래스가 다르면 각각 다른 파일에 저장해도 된다.

 

 

8. 클래스를 인스턴스화해서 여러 개의 프로그램을 돌려 봅니다.

인스턴스는 하나의 클래스를 복제해서 서로 다른 데이터의 값과 서로 같은 메소드를 가진 복제본을 만드는 것이다.

 

메소드로 구조를 잡고 ~ 그걸로 클래스로 구조를 잡고 ~ 그 클래스를 복제한 인스턴스로 구조를 잡는다.

 

내가 원하는 프로그램의 내용. 구상

조건에 따라서 다른 출력을 내고 싶다.

1. OO 상품

  • 공급가 : 10000
  • 부가가치세율 10%
  • 공급가 대비 비용률 : 30%

2. XX 상품

  • 공급가 : 20000
  • 부가가치세율 5%
  • 공급가 대비 비용률 : 20%

 

이 때 각각의 상태에 따라 인스턴스를 생성해서 실행하는 방법이 있다.

우선 Accounting 클래스의 static 키워드를 모두 제거.

이번 상황에서는 두 가지 상태가 있기 때문에 두 개의 인스턴스를 생성. (new 를 사용)

그리고 각각의 인스턴스를 상태에 맞추어 조절. (a1. ~~~ , a2. ~~~)

class Accounting{
		public double valueOfSupply; //전역변수
		public double vatRate;
		public double expenseRate;
		public void print() {
			System.out.println("Value of supply : "+valueOfSupply);
			System.out.println("VAT : "+ getVAT() );
			System.out.println("Total : "+ getTotal() );
			System.out.println("Expense : "+getExpense() );
			System.out.println("Income : "+ getIncome() );
			System.out.println("Dividend 1 : "+ getDiviend1() ); // 1번 배당
			System.out.println("Dividend 2 : "+ getDiviend2() ); // 2번 배당
			System.out.println("Dividend 3 : "+ getDiviend3() ); // 3번 배당
		}
		public double getDiviend3() {
			return getIncome() * 0.2;
		}
		public double getDiviend2() {
			return getIncome() * 0.3;
		}
		public double getDiviend1() {
			return getIncome() * 0.5;
		}
		public double getIncome() {
			return valueOfSupply - getExpense();
		}
		public double getExpense() {
			return valueOfSupply * expenseRate;
		}
		public double getTotal() {
			return valueOfSupply + getVAT();
		}
		public double getVAT() {
			return valueOfSupply * vatRate;
		}
}

public class AccountingClassApp {
	
	public static void main(String[] args) {
		//Accounting.valueOfSupply = 10000;
		//Accounting.vatRate = 0.1;
		//Accounting.expenseRate = 0.3;
		//Accounting.print();
		
		// new Accounting >> Accounting클래스를 복제하는 것
		// 윗 부분에서 static을 지워야한다.
		// instance
		Accounting a1 = new Accounting();
		a1.valueOfSupply = 10000.0;
		a1.vatRate = 0.1;
		a1.expenseRate = 0.3;
		a1.print();
		
		Accounting a2 = new Accounting();
		a2.valueOfSupply = 20000.0;
		a2.vatRate = 0.05;
		a2.expenseRate = 0.2;
		a2.print();
		
	}
}