메소드는 클래스의 동작을 나타내는 함수이다.
이전의 Math 클래스의 floor, ceil, PrintWriter의 write, close 등이 메소드이다.
public class AccountingMethodApp {
public static double valueOfSupply;
public static double vatRate;
public static double expenseRate;
public static void main(String[] args) {
valueOfSupply = 10000.0;
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());
System.out.println("Dividend 2 : " + getDiviend2());
System.out.println("Dividend 3 : " + getDiviend3());
}
public static double getDiviend1() {
return getIncome() * 0.5;
}
public static double getDiviend2() {
return getIncome() * 0.3;
}
public static double getDiviend3() {
return getIncome() * 0.2;
}
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;
}
}
만약, 우리가 계산해야 하는 작업이 1줄짜리 코드가 아니라 1억줄 짜리 코드였다고 생각해보자.
그 1억줄 짜리 코드를 한줄로 표현하고, 원래 1억줄 짜리 코드는 다른곳에 숨겨둔다면, 편리하지 않을까?
메소드를 사용하면 위와 같은 작업이 가능하다.
메소드를 이용하여 코드 수정
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; } }
- vat를 구하는 getVAT 메소드가 만들어졌다.
- vat 변수는 getVAT 메소드를 통해 값을 가져온다.
- getVAT 변수는 main 메소드의 내부 변수(지역변수)인 valueOfSupply와 vatRate를 파라미터로 사용한다.
메소드의 파라미터를 없애려면?
- getVAT 메소드의 파라미터를 위와같이 수정하면 에러가 발생한다.
- valueOfSupply 변수는 main메소드 안에서 선언되었기 때문에, main 안에서만 실행 될 수 있는 지역변수이다.
- valueOfSupply, vatRate 변수를 AccountingMethodApp 클래스의 전역변수로 선언하면 모든 메소드에서 접근할 수 있다.
- getVAT의 아규먼트로 주고 있는 valueOfSupply와 vatRate 변수에서
Refactor - Convert Local Variable to Filed
를 클릭한다.- 전역 변수는 Field라고도 한다.
- 변수 이름을 지정하고 public 변수로 만든다.
- valueOfSupply는 클래스 어디에서도 접근할 수 있는 전역변수가 되었다.
- 변수의 값은 main 메소드 안에서 할당하고 있음을 확인할 수 있다.
다른 변수들도 메소드화 해보자.
출력하는 부분 메소드로 정리하기
public class AccountingMethodApp { ... 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 : " + getDividend1()); System.out.println("Dividend 2 : " + getDividend2()); System.out.println("Dividend 3 : " + getDividend3()); } ... }
- main 메소드 안의 지역변수들은 필요 없어졌기 떄문에 모두 지워도 상관없다.
- main 메소드 안의 동작들은 단순해졌고, 세부 동작들은 다른 메소드 안에서 정의되어 사용자 입장에서 보기 단정한 코드로 바뀌었다.
메소드를 이용하면 코드가 그룹화되어 정리되기 때문에 코드의 가독성이 높아진다.
만약 프로그램이 돈 계산 외에 다른 여러 작업을 수행해야 한다면, 프로그램은 더욱 복잡해질 것이다.
그렇다면 코드 내의 메소드와 변수 또한 섞여서 복잡해질 것이다.
이런 상황은 클래스로 해결할 수 있다.
클래스는 서로 연관된 변수와 메소드를 묶어놓은 것이다.
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());
System.out.println("Dividend 2 : " + getDiviend2());
System.out.println("Dividend 3 : " + getDiviend3());
}
public static double getDiviend1() {
return getIncome() * 0.5;
}
public static double getDiviend2() {
return getIncome() * 0.3;
}
public static double getDiviend3() {
return getIncome() * 0.2;
}
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.0;
Accounting.vatRate = 0.1;
Accounting.expenseRate = 0.3;
Accounting.print();
// anotherVariable = ...;
// anotherMethod = ...;
}
}
이클립스의 상단 Window - Show View - Outline
을 클릭해보자.
편집기로 돌아와서, 맨 위에 Accounting 클래스를 생성해보자.
Accounting 클래스 생성
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()); System.out.println("Dividend 2 : " + getDiviend2()); System.out.println("Dividend 3 : " + getDiviend3()); } public static double getDiviend1() { return getIncome() * 0.5; } public static double getDiviend2() { return getIncome() * 0.3; } public static double getDiviend3() { return getIncome() * 0.2; } 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 { ... }
- Outline이 변경된 것을 확인할 수 있다.
클래스 생성 후 main 메소드 수정
public class AccountingClassApp { public static void main(String[] args) { Accounting.valueOfSupply = 10000.0; Accounting.vatRate = 0.1; Accounting.expenseRate = 0.3; Accounting.print(); } }
- valueOfSupply, vatRate, expenseRate 변수와 print 메소드가 Accounting 클래스의 멤버가 되었기 떄문에 main 메소드를 위와 같이 수정해준다.
인스턴스는 클래스를 실제로 실행시킨 실체와된 클래스라고 할 수있다.
인스턴스를 활용하면 다양한 상태에 있는 여러개의 클래스를 돌릴 수 있게된다.
즉, 클래스를 복제해서 서로 다른 데이터, 서로 같은 메소드를 가진 복제본을 만드는 것이 인스턴스이다.
위의 AccountingClassApp 클래스를 수정해보자.
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());
System.out.println("Dividend 2 : " + getDiviend2());
System.out.println("Dividend 3 : " + getDiviend3());
}
public double getDiviend1() {
return getIncome() * 0.5;
}
public double getDiviend2() {
return getIncome() * 0.3;
}
public double getDiviend3() {
return getIncome() * 0.2;
}
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) {
// 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();
a1.print();
}
}
여러 조건에 따라 다른 출력을 내고 싶다고 가정해보자.
- OO 상품
- 공급가 : 10000
- 부가가치세율 10%
- 공급가 대비 비용률 : 30%
- XX 상품
- 공급가 : 20000
- 부가가치세율 5%
- 공급가 대비 비용률 : 20%
and so on...
- 이런 경우 변수를 조정하는 과정에서 프로그램이 꼬일 수 있다.
- 이때 각각의 상태에 따라 인스턴스를 생성해서 실행하면 문제를 해결할 수 있다.
Accounting 클래스
public double valueOfSupply; public double vatRate; public double expenseRate;
- Accounting 클래스의 static 키워드를 모두 제거한다.
main 메소드
Accounting a1 = new Accounting(); Accounting a2 = new Accounting();
- 위의 가정에서 두가지 상태가 있기 떄문에 두개의 인스턴스를 생성한다.
.... 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(); ....
- 각각의 인스턴스를 위의 가정에 맞게 상태에 맞추어 조절해 준다.
- a1 인스턴스는 a2 인스턴스의 작업이 끝난 후에도 계속 남아있기 때문에, 마지막에 a1 인스턴스의 print 메소드를 실행해도 같은 결과를 출력해 준다.
메소드로 코드를 그룹화하여 구조를 잡고, 이런 메소드를 묶어 클래스로 구조를 잡고, 조건에 따라 인스턴스를 사용하는 이러한 방식이 자바의 기본 시스템이라고 할 수 있다.
부스트코스 쉽게 배우는 자바 1
https://www.boostcourse.org/cs126