TIP
메소드 하나씩 지우고 같은 결과 나오게 해보기
-> 메소드의 의미가 뭔지, 왜 저 메소드가 필요한지 역으로 따라가며 확인해보는 것.
- toString
목적: 객체가 담고있는 내용(멤버변수, 멤버변수로 유도할 수 있는 내용들)을 문자열로 바꾸어 전달하는 것 (누구에게? 불러낸 사람(지금까지는 main)에게!
- 정해진 형태X 클래스를 만드는 사람이 '문자열'로 내보내고 싶은 내용을 내보내도록 정의하면 됨
굉~~~장히 많이 쓰임
헤더(특히 이름)는 목적·역할이 명확하게 드러나야 함
/* 헤더만 보고 무엇을 하는 메소드인지 어떤 역할인지 알 수 있어야 함 이름만 봐도 String으로 변환하는 메소드임을 알 수 있음 */ public String toString(){ ... }
프로그래밍에 정답은 없지만 최선은 있다.
같은 목적이라도 다른 형태로 만들 수 있지만, 최선의 코드는 비슷하게 수렴한다.
우리는 그것을 찾아야 한다.
[UML] UML 다이어그램 종류 및 기본
[UML] Class Diagram 기본
UML(Unified Modeling Language)의 구성요소 중 하나
코드의 설계도
사람이 사용하는 말(글)만으로는 설계 과정에서 오차가 생길 수 있음
(나는 당연히 toString 사용해서 이렇게 처리하겠지~ 하고 넘겼는데, 동료는 다른 방식으로 처리한다던지, 고객의 요구사항이 내가 생각한 것과 다르다던지~)
그걸 해결하기 위해 그림으로 표현하자! 한 것이 UML
접근설명자 access modify
public + , private -, protected #, 생략 ~ (앞 두 개가 99%)
신입 개발자로 들어갈 때는 최소한 UML 종류는 다 알고 가야 할 것
(UML - 클래스 / 유스케이스 / 시퀀스 / ...)
UML 개발자 세 명을 three 아미고스 - 세 명의 선각자로 부름. 레셔널 sw. 레셔널 로즈. 그레디 부치 이바 제이콥슨 제임스 럼바우
현실의 객체 - 특징 뽑기 - 상태와 행위로 분류 - 클래스 다이어그램 -
실제 현실에 있는 기능을 가져와서 사람에게 어떻게 설명할 건지? 가 중요
p. 150 Box클래스의 클래스 다이어그램
class Box { int width; int length; int height; double getVoume(){ ... return (double) ... } }
class Television {
int channel; // 채널 번호
int volume; // 볼륨
boolean onOff; // 전원 상태
public String toString(){
return "텔레비전의 채널은 " + channel + "이고 볼륨은 " + volume + "입니다.";
}
}
class TelevisionTest {
public static void main(String[] args) {
Television myTv = new Television();
myTv.channel=7;
myTv.volume = 10;
myTv.onOff = true;
Television yourTv = new Television();
yourTv.channel = 9;
yourTv.volume = 12;
yourTv.onOff = true;
// 문자열과 합쳐지며 myTv를 문자열로 변경 -> toString 호출 -> return값 반환
System.out.println("나의 " + myTv);
System.out.println("너의 " + yourTv);
}
}
class Some {
int num;
public String toString(){
return "num: " + num;
}
}
class UseSome {
public static void main(String[] args) {
Some s1 = new Some();
s1.num = 3;
Some s2 = new Some();
s2.num = 7;
s1 = s2; // s1이 s2 객체의 주소를 가져라
System.out.println("s1: " + s1);
System.out.println("s2: " + s2);
// 둘 다 s2의 값을 반환함
}
}
- null이란?
'나타내는 값이 없음'을 의미하는 '값'!
값이므로 변수에 대입하여 초기화 가능
❗❗ 모든 참조형 변수가 가질 수 있는 공통된 값 ❗❗
= [Java] 예외가 발생했습니다. (exception error)
class Some {
int num;
public String toString(){
return "num: " + num;
}
}
class UseSome {
public static void main(String[] args) {
Some s1 = new Some();
s1.num = 3;
Some s2 = new Some();
s2.num = 7;
// s1 = null인데 그 안의 num에 4를 넣으라는 명령
s1 = null;
s1.num = 4;
System.out.println("s1: " + s1);
System.out.println("s2: " + s2);
}
}
컴파일 과정에서는 값을 대입하지 않고 '문법'만 확인하므로 에러가 뜨지 않음
하지만 실제로 실행하면 에러가 뜸
ex) System.out.println(4/0); // runtime 에러
언제 누가 무슨 목적으로 만들었고 변수는 무슨 의미고 파라미터는 무슨 의미고 - 등등을 주석으로 꼭 적어주기 - 코드가 복잡해질수록 필요 - 자기도 까먹는다
/*
재고 Stock
===========================
상품번호 ~ id : String
재고수량 ~ count : int
===========================
증가() ~ increase(amount:int):void
감소() ~ decrease(amount:int):void
*/
class Stock {
String id; // 상품번호
int count; // 재고수량
void increase(int amount){
// 'amount만큼의 양을 count에 더하는' 메소드
printHeader(amount, "증가");
if(isPositive(amount)){ // amount가 양수인지 확인
count += amount; // amount만큼의 양을 count에 더하는
printInfo(); // '재고 출력' 메소드
}
}
void decrease(int amount){
// 'amount만큼의 양을 count에 빼는' 메소드 +
printHeader(amount, "감소");
if(isPositive(amount)){
if(amount <= count){
count -= amount;
printInfo();
} else {
System.out.println("재고가 부족합니다.");
}
}
}
public String toString(){
// '출력할 문자열(상품번호, 재고수량) 반환' 메소드
return id + "(" + count + ")";
}
void printHeader(int amount, String what){
// '증감 명령 확인용 출력' 메소드
System.out.printf("재고(%s) 수량을 %s(%d) : ", id, what, amount);
}
void printInfo(){
// ''toString 문자열' 출력' 메소드
System.out.println(toString());
}
boolean isPositive(int amount){
// 'amount가 양수인지 확인하는' 메소드
boolean result = true;
if(amount <= 0){
System.out.println("증감 수량은 0보다 큰 값이어야 합니다.");
}
return result;
}
}
class UseStock {
public static void main(String[] args) {
Stock s = new Stock();
s.id = "s001";
s.count = 30;
s.increase(40);
s.decrease(200);
}
}
/*
강아지
이름
종
색깔
짖기()
물기()
먹기()
Dog
=========================
~ name : String
~ breed : String
~ color : String
~ food : int = 0
~ disk : String = "white"
=========================
~ bark(): void
~ bite(): void
~ feed(amount:int):void
~ fill(amount:int):void
~ react():void
~ printflyingDisk():void
*/
class Dog {
String name;
String breed;
String color;
int food = 0;
String diskColor = "하양";
void bark(){
System.out.printf("멍멍\n강아지가 별로 좋아하지 않는 것 같아\n\n");
}
void bite(){
System.out.printf("강아지가 원반을 꽉 물었어\n강아지가 무척 좋아하는 것 같아\n\n");
}
void feed(int amount){
System.out.println("강아지가 사료를 먹고 있어");
printCmd("-",amount);
if(isPositive(amount)){
if(amount <= food){
food -= amount;
} else {
System.out.printf("사료가 부족한 것 같아 \n채워주자 \n");
}
}
printInfo();
}
void fill(int amount){
System.out.println("주인이 사료를 채우고 있어");
printCmd("+",amount);
if(isPositive(amount)){
if(amount + food <= 100){
food += amount;
} else {
System.out.printf("사료가 넘칠 것 같아 \n강아지가 먹을 때까지 기다리자\n");
}
}
printInfo();
}
public String toString(){
return "현재 사료량: " + food + "\n\n";
}
void printInfo(){
System.out.printf(toString());
}
void printCmd(String symbol, int amount){
System.out.printf("사료: %d %s %d \n", food, symbol, amount);
}
boolean isPositive(int amount){
boolean result = amount > 0;
if(!result){
System.out.println("0 이상의 숫자를 써주세요");
}
return result;
}
void printFlyingDisk(){
System.out.printf("%s 원반을 던졌다\n", diskColor);
}
void react(){
printFlyingDisk();
if(diskColor == "하양"){
bite();
} else {
bark();
}
}
}
public class Quiz2 {
public static void main(String[] args) {
Dog d = new Dog();
d.name = "황구";
d.breed = "시바견";
d.color = "노랑";
d.food = 100;
d.printInfo();
d.feed(50);
d.fill(30);
d.feed(-10);
d.fill(-10);
d.feed(90);
d.fill(30);
System.out.println("강아지는 하얀 원반을 좋아해\n");
d.react();
d.diskColor = "검정";
d.react();
}
}
BankAccount는 잔고를 나타내는 정수형 멤버 변수(balance)를 가지고 있고 예금을 인출하는 메소드( withdraw)와 예금을 입금하는 메소드(deposit), 현재의 잔고를 반환하는 메소드(getBalance), 현재 잔액에 대하여 연 7.5% 의 이자를 계산하여 추가하는 메소드(addlnterest) 를 가지고 있다.
/*
===========================================
BankAccount
===========================================
~ balance : int
===========================================
~ deposit(amount:int):void
~ withdraw(amount:int):void
~ getBalance():int
~ addInterest(year:int):void
===========================================
*/
class BankAccount{
int balance;
void withdraw(int amount){
// balance withdraw (amount) M
printInfo(amount, "인출");
if(isPositive(amount)){
balance -= amount;
printBalance();
}
}
void deposit(int amount){
// balance deposit (amount) M
printInfo(amount, "입금");
if(isPositive(amount)){
balance += amount;
printBalance();
}
}
int getBalance(){
// return balance(int) M
return balance;
}
void addInterest(int year){
// 7.5% per year M
int interest = (int) (balance * 0.075 * year);
printInfo(interest, "이자");
balance += interest;
printBalance();
}
void printBalance(){
// print balance M
System.out.println("deposit: " + getBalance() + "원");
}
boolean isPositive(int amount){
// amount > 0 ? M
boolean result = amount > 0;
if(!result){
System.out.println("입출액은 0보다 커야 합니다.");
}
return result;
}
void printInfo(int amount, String what){
// command review M
System.out.printf("----- %s: %d원 -----\n", what, amount);
}
}
public class Quiz3 {
public static void main(String[] args) {
BankAccount ba = new BankAccount();
ba.balance = 100000;
ba.printBalance();
ba.withdraw(50000);
ba.deposit(70000);
ba.withdraw(-50000);
ba.deposit(-70000);
ba.addInterest(10);
}
}