오늘은 상담 및 클래스 설계 발표하는 시간이라서 개념을 새로 배우지는 않고 어제 배웠던 붕어빵 부분의 이해를 더 자세하게 하려고 했다. 워낙 객체 지향, 자바의 개념이 어렵기에, 이해가 많이 안 가서 자문자답하면서 적어놓은 것을 올리고자 한다.
/*
* 주의 : 하단에는 부적확한 정보와, 혼잣말과, 추측이 난무한 주석들이 많습니다. 감안하고 봐주세요.
*/
class 붕어빵 { // 클래스 선언 == 붕어빵을 만들어 낼 틀 == 물건
String 앙꼬; // 속성=멤버변수=field 선언 == 물건의 속성
String 앙꼬 = 팥; // 이런식으로 멤버변수 선언해줌과 동시에 값을 집어넣어주는 것을 초기화라고 한다. 이런 값은 초기값이라고 함.
붕어빵() { // 생성자 선언
// Q. 생성자란 뭘까? : 객체가 생성될 때 하는 일(기능) == 붕어빵틀()
// 그래 생성자가 그런 일을 해
// Q. 근데, 생성자를 만들어주라고해서 만들어주긴 하는데, 왜 꼭 필요한걸까?
// Q. 혹시, 지정해 둔 속성을 생성자에서 사용하기 위해서일까?
// 그래 어찌됐든 여기에 앙꼬를 고정으로 지정해줄거야
앙꼬 = "팥";
}
붕어빵(String 앙꼬) { // 생성자 선언
// 얘는 멤버변수를 유동적으로 받을 수 있는 생성자를 선언해준거야
this.앙꼬 = 앙꼬;
// 이렇게 써주는 이유는, this로 받으면 내가 쩌기 위에 String 앙꼬;를 null값으로 지정해놨지
// 만약, 앙꼬 = 앙꼬;로 초기화 했다면, 앙꼬 = null; null이 계속해서 출력이 될거야
// 그러니까, 얘를 null로 안 만드려고 메소드에서 값을 입력하면 그 입력한 값을 받아서
// 사용하고 싶기 때문에 this라는 예약어(?)로 그 값을 받아오는 거야 그럼 앙꼬는 전역변수로 사용할 수 있게 돼
// 사실 나도 여기가 이해가 잘 안돼,,, 머리로는 이해가 되는데 말로 설명을 못하겠어
// 그럼 모르는 거야
// Q. this가 하는 정확한 역할은 뭘까?
// Q. 굳이 생성자 선언을 2개로 나눠서 하나는 고정값, 하나는 유동적인 값을 받는 이유가 뭘까?
// Q. 생성자는 한 번에 한 개의 일(기능)밖에 못하나?
}
void 배부르게하다() { // 메소드 선언
// Q. 메소드란 뭘까? : 객체가 할 수 있는 일(기능) == 배부르게한다()
// 메소드는 하는 일이 비교적 명확해
// 객체가 하는 동사형의 일을 말하거든
// 배부르게 하는 것을 컴퓨터 위에 작업하는 프로그래밍상 우리가 직접 누군가를 배부르게 할 수가 없잖아
// 그러니까 이걸 출력 메소드로 표현할거야
System.out.println("배부르게 한다.");
}
}
// 그러면 여기까지 거래가 이루어질 물건에 대한 클래스 선언은 마쳤어
// 이제 판매자의 클래스 선언을 해줄거야
class 아줌마 { // 클래스 선언 == 판매자
int 나이; // 속성=멤버변수=field 선언 == 판매자의 속성
붕어빵 빵1, 빵2; // 타입 - 변수 이렇게 선언해준거야
// 원래라면 이렇게 적어줘야돼
// 붕어빵 빵1;
// 붕어빵 빵2;
// 그런데 어차피 붕어빵이라는 똑같은 타입을 사용하니까 붕어빵 빵1, 빵2;라고 선언해준거야
아줌마(){ // 생성자 선언 = 객체가 생성될 때 하는 일(기능)
나이 = 40; // 나이라는 멤버변수에 고정값으로 선언해줬어
}
// 그럼 이제 아줌마가 하는 일, 즉 메소드를 선언해줘야겠지?
// 이 아줌마가 할 수 있는 일에 대해서 선언을 해주는거야
void 굽는다() {
// 굽는다 하는데, 구워야 할 대상을 불러와야겠지?
// 대상을 어떻게 부르냐
붕어빵 빵1 = new 붕어빵(); // 빵1에 들어갈 생성자를 호출해준 거고,
붕어빵 빵2 = new 붕어빵("슈크림"); // 빵2에 들어갈 생성자를 호출해준거야
// 일단 여기서는 붕어빵이라는 생성자를 호출해주는 역할로만 다 할거야
// 왜 여기서는 붕어빵을 호출해주는 걸로만 끝나는 것인가?
// 생성자를 호출해주는 것만 하기에는 할 일이 너무 없잖아
// 그래서 굽는다 라는 말을 출력해주려고 해
System.out.println("붕어빵을 굽는다");
}
}
// 그러면 여기까지 판매자에 대한 클래스 선언은 마쳤어
// 이제 구매자의 클래스 선언을 해줄거야
class 손님 { // 클래스 선언 == 구매자
// 손님에겐 돈이 있어야 물건을 살 수 있겠지?
int 돈 = 1000; // 속성=멤버변수=field 선언 == 손님의 속성1 == 손님이 가지고 있는 액수
String 이름 = "철수"; // 속성=멤버변수=field 선언 == 손님의 속성2 == 손님의 이름
손님() { // 생성자 선언 == 객체가 생성될 때 하는 일(기능)
돈 = 돈 - 300; // 붕어빵의 값은 곧 700원이라는 이야기가 되지
return 빵; // 빵의 값을 리턴해줘
}
}
// 일단 여기까지 구매자의 클래스 선언도 마쳤어
// 이제 메인 메소드를 관장하는 신으로 넘어가보자
객체가 생성될 때 하는 일(기능) == 붕어빵틀()
class 신 { // 클래스 선언 == 메인 메소드를 실행시킬 메인 클래스
// 이 모든 객체를 만들고, 지켜볼 인물인 신이 필요해 그래서 신 클래스를 만든거야
public static void main(String[] args) { // 메인 메소드가 있어야 무조건 자바를 실행할 수 있지?
// 그래서 신 클래스 안에다가 메인 메소드를 선언해준거야
아줌마 주인 = new 아줌마(); // 판매자의 생성자를 호출해주었어
// 생성자를 호출할 때는 아줌마라는 클래스명을 선언해주고 그 다음 임의로 지을 변수명을 선언해줘
// 선생님이 말씀해주셨던 것 중 클래스는 좀 더 포괄적인 개념이고
// 객체는 클래스가 만들어 낸 틀 안에서 다양한 속성을 가진 더 세부적인 개념이라면
// 아줌마가 객체가 되고 주인이 클래스가 되어야 한다고 생각해
// 뭐 어찌됐든간에 아줌마라고 이미 선언해놨으니까 그건 차치해두고,
// 이 아줌마를 선언해줬으니까 이 아줌마가 가지고 있는 속성과 메소드를 우리는 이제 사용할 수 있어
System.out.print("나이가 " + 주인.나이+"세인 아줌마가 ");
주인.굽는다();
System.out.print("첫번째 붕어빵의 앙꼬는 " + 주인.빵1.앙꼬+ "이고, "); // 주인이라는 클래스의 빵1라는 멤버변수, 빵1의 앙꼬는 빵1의 멤버변수라는 뜻이다. chaining이라는 개념암
System.out.println("두번째 붕어빵의 앙꼬는 " + 주인.빵2.앙꼬+ "이다."); // 주인이라는 클래스의 빵2라는 멤버변수, 빵2의 앙꼬는 빵2의 멤버변수라는 뜻이다. chaining이라는 개념암
System.out.println();
손님 손 = new 손님(); // 손님이라는 생성자를 손이라는 변수에 담는다
붕어빵 빵 = 손.구매한다(주인.빵2); // 손이라는 객체에 구매한다라는 메소드를 사용한다, 객체로 부르면 파라미터 변수가 되는 것
// 관점마다 이름이 다른 것이다
System.out.println(
손.이름+"가 붕어빵(앙꼬:"+빵.앙꼬+")을 구매하고, "
+손.돈+"원이 남았어요");
System.out.print("붕어빵은 "+손.이름+"를 ");
빵.배부르게하다();
}
}
Non-static variable cannot be referenced from a static context
비정적 변수는 정적 컨텍스트에서 참조 할 수 없습니다.