오늘부터 객체지향 파트가 시작되었다.
걱정은 했었지만 역시 걱정한만큼 어려웠다;;;
하지만 어찌 하겠는가. 이해할때까지 계속 보고 이해하려고 해보는 수밖에
그럼 오늘내용도 이해한 만큼이라도 정리해 보려고 한다.
일단 기초로 알아야할 내용은 Java는 "객체지향 프로그래밍" 언어라는 것이다.
"객체지향 프로그래밍" 에서 객체란 현실이나 개념으로 존재하는 무언가라고 할수있다. 간단히 생각하자면 에어컨이나
선풍기처럼 이미 만들어져있는 무언가일 것이다.
C언어를 설명할 때 주로 "절차지향 프로그래밍"언어라고 한다. 절차지향이 순서대로 진행한다는 뜻도 맞지만 , 함수가 코드의 기본단위가 된다는 말이다.
반면, 자바의 객체는 변수와 함수(속성과 기능)을 내장할 수 있다.
어떤 속성과 기능이 내장되어 있냐에 따라서 객체 생성 및 함수호출 만으로도 대부분의 객체가 상호작용을
진행하며 코드를 전개할수 있다.
이렇게 객체를 성계하는 내용이 중요하기 때문에 객체를 만들기 위해 자료형, 클래스의 문법을 읽고 해석하는 데에
많은 공부가 필요하다.
class Member{
// 멤버 필드
String name;
int age;
// 멤버 메서드
void show(){
int test = 5;
System.out.printf("이름은 %s이고, 나이는 %d살 입니다\n", name, age);
}
멤버 메서드는 보통 설계도라고들 한다. 물건을 만들기 위해서는 설계도가 필요하듯이 객체도 메서의 에 의해 기능이 구현된다.
메서드는 함수이므로 반환형, 함수이름, 매개변수를 지정하고 내용을 작성한다. 그리고 서로 다른 객체라도 같은 메서드를 수행할 수 있다. 내용은 필드의 값에 따라 달라진다.
'필드'란 객체가 생성되면 객체의 속성을 저장할 수 있는 변수를 뜻한다. 초기값을 지정할 수도 있고 지정하지 않았다면 0으로 채워진다.
생성자란 객체를 생성하기 위해서 반드시 호출해야 하는 함수이다. 대표적인 특징으로는 반환형을 작성하지 않으며 함수 이름이 클래스의 이름과 같아야 한다.
이 또한 함수이므로 오버로딩이 가능하며(물론 메서드도 가능) 생성자 내에서 또 다른 생성자를 호출할 수 있다.
생성자 내부에서 다른 생성자를 호출할 때는 this() 형식으로 호출해야 한다.
그럼 실전사용예시를 보자.
class Ball {
}
class kid {
String name;
Ball ball;
kid(String name){
this.name = name;
}
void setBall(Ball ball) {
this.ball = ball;
}
void throwBall(kid other) {
other.ball = ball;
this.ball = null;
}
boolean hasBall() {
return ball != null;
}
}
public class Ex05_Reference {
public static void main(String[] args) {
kid p1 = new kid("짱구");
kid p2 = new kid("훈이");
Ball ball = new Ball();
p1.setBall(ball);
System.out.println(p1.name+"가 공을 가지고 있는가 : " + p1.hasBall());
System.out.println(p2.name+"가 공을 가지고 있는가 : " + p2.hasBall());
System.out.println();
p1.throwBall(p2);
System.out.println("짱구가 공을 가지고 있는가 : " + p1.hasBall());
System.out.println("훈이가 공을 가지고 있는가 : " + p2.hasBall());
System.out.println();
p2.throwBall(p1);
System.out.println("짱구가 공을 가지고 있는가 : " + p1.hasBall());
System.out.println("훈이가 공을 가지고 있는가 : " + p2.hasBall());
System.out.println();
}
}
일단 Ball과 kid이라는 클래스를 만든다.
Ball클래스는 타입을 지정해 주기 위해 만 든 것이지 딱히 의미가 있는 것은 아니다.
kid클래스에서 필드변수 String name, Ball타입의 ball을 만들고
kid(String name){ // 매개변수
this.name = name;
필드변수 자신 매개변수
kid클래스의 매개변수인 name을 만들고 필드변수 name을 this로 불러주고 매개변수 name을 넣어준다.
void setBall(Ball ball) {
this.ball = ball;
이것은 setBall이라는 메서드 함수를 생성한 것이다. Ball타입의 ball변수를 만들고
필드변수 ball변수에 setBall메서드에서 생성한 매개변수 ball을 넣는다.
이것을 공 주고받기와 비유한다면 외부에서 공을 받아서, 내가 가지게 하는 것과 같다.
void throwBall(kid other) {
other.ball = ball;
this.ball = null;
}
그리고 kid클래스 타입의 other변수를 생성하고
ball(공)을 other.ball 다른 사람에게 공을 넘겨주고(참조)
내 공인 this.ball을 비워버린다.
이것을 p1과 p2라는 객체에 각각 '짱구'와 '훈이'라는 이름을 부여하고
Ball타입의 ball이라는 객체도 생성한다.
첫 번째 출력문은 p1.setBall(ball)인데
간단히 생각해서 p1(짱구)이 공을 얻었다는 상황이며
p1.throwBall(p2)은 짱구가 훈이에게 공을 주는 상황인 것이며,
이렇게 되면 짱구는 빈손이 되는 거다.
여기서 (p2)는 throwBall의 매개변수 other와 이어지는 것을 의미한다.
그럼 더욱 어려운 내용으로 가보자.
이건 아직도 완벽하게 이해했다고 말하지 못할 것 같다.
일단 아래 코드는 메시지를 보내서 보낸 사람은 보낸 내용이, 받은 사람은 상대방의 전화번호와 "잘 받았다"라는 글을 표시해 주는 코드이다.
public class Main {
public static void main(String[] args) {
Phone p1 = new Phone("010-1234-1234");
Phone p2 = new Phone("010-2222-2222");
Scanner sc = new Scanner(System.in);
// System.out.print("메시지를 보낼 대상의 전화번호를 입력 : ");
// String targetNumber = sc.nextLine(); // 010-2222-2222
System.out.print("보낼 메시지를 입력 : ");
String content = sc.nextLine(); // 아무 내용
System.out.println();
p1.sendMessage(p2, content);
// p1이 p2에게 메시지를 보내면
// p2에서 메시지를 받았을 때, 보낸사람의 번호와 받은 메시지의 내용을 출력해야 합니다
p2.sendMessage(p1, "잘받았다");
sc.close();
}
}
이 두 클래스는 서로 상호작용하고 있다. 일단 아래의 Phone 클래스를 보면 필드변수 pnum(전화번호)를 생성한다.
그리고 Phone클래스의 생성자를 생성하고 필드변수에 매개변수를 참조해 준다.
이다음이 처음 보는 사람은 헷갈릴 수 있는데
void sendMessage(Phone target, String content)
target.recieveMessage(this, content);
이 코드는 매개변수 받는 사람과 보낸 내용을 매개변수로 만들고 받는 사람의
void recieveMessage(Phone sender, String content) {
System.out.printf("[%s 의 화면]\n", this.pnum);
System.out.printf("%s : %s\n", sender.pnum, content);
System.out.println();
recieveMessage메서드를 실행한다. 즉
p1.sendMessage(p2, content)를 쓰면 p1이 p2에게 메시지를 보내면 p2의 화면에 보낸 사람의 전화번호와 내용이 화면에 뜨게 하는 것이다. 이 내용이 recieveMessage(this, content) 이것인데 recieveMessage의 this, 이것은 아래의 Sender값을 불러오기 위해서이다. 그리고 content를 불러와 recieveMessage의 출력포맷에 맞춰 출력하는 것이다.
public class Phone {
String pnum;
Phone(String pnum) {
this.pnum = pnum;
}
// 보내는 사람의 입장에서 서술한 메서드
// target은 메시지를 받을 사람, content는 메시지의 내용
void sendMessage(Phone target, String content) {
target.recieveMessage(this, content);
}
// 받는 사람의 입장에서 서술한 메서드
// sender는 나에게 메시지를 보낸 사람
// content는 메시지의 내용
void recieveMessage(Phone sender, String content) {
System.out.printf("[%s 의 화면]\n", this.pnum);
System.out.printf("%s : %s\n", sender.pnum, content);
System.out.println();
}
}
이걸 혼자 짤 수 있을지는 미지수겠지만 일단 블로그를 정리하면서 어느 정도 틀은 잡힌 것 같다.
내가 현재 다니고 있는 국비과정은 매주 배운 내용을 바탕으로 프로그램을 만드는 시험이 있고 낙제점을 받으면 재시험이 있고 3번 떨어지면 학원에서 제명당한다고 한다.
당연히 항상 집중하고 매일 공부하고 있으니 떨어질 것 같진 않지만 그래도 부담으로 다가오는 것은 당연한 것인 것 같다.
아직은 버틸 만 하지만 백엔드파트에 본격적으로 들어가면 지금 이상의 각오를 해야 할 것 같다.
이제 10일 차다. 당연할 얘기지만 하루하루 배운 내용을 이해하고 지식이 쌓이다 보면 지금 보면 어려운 내용도 조금은 더욱 편하게 느껴질 것이다.
인생의 한 번밖에 없는 기회 한번 힘들어도 어떻게는 최고의 결과를 만들어보자. 지금 나 자신이 못한다고 계속 낙담하는 것보다 앞으로 어떻게 하면 극복할 수 있을까를 생각하며 오늘은 여기서 마치겠다.
'JAVA 공부' 카테고리의 다른 글
자비의 기초 - 객체지향파트(생성자,메서드, 함수 심화) (0) | 2023.03.26 |
---|---|
블로그 복붙방지 코드(개인용) (0) | 2023.03.24 |
자바의 기초 - loop문 응용, array(배열) (0) | 2023.03.19 |
자바의 기초 - for문 (0) | 2023.03.17 |
자바의 기초 - String(문자열) (0) | 2023.03.15 |