- 자바는 흔히들 객체지향 프로그래밍(Object-Oriented Programming, OOP) 언어라 부른다.
객체지향은 우리가 알고 있는 대표적인 프로그래밍 언어인 C가 비교적 명령어의 목록으로 구성되는 것과 달리 컴퓨터 프로그램을 여러 객체들의 모임으로 바라보는 것이다. 이때 객체는 서로 메시지를 주고받고 데이터를 처리한다.
처음 객체지향이라는 것을 접했을 때는 평소 잘 쓰이지 않는 단어인 객체라는 것에 대한 이해가 정말 어려웠고 아직까지도 누군가 객체가 뭐냐고 물어봤을때 확신을 가지고 설명하기엔 부족함이 많다. 다만 지금까지 봐온 객체와 관련된 많은 설명중 개인적으로 가장 와닿는 말은 '객체란 메소드와 그에 관련된 변수들을 묶어 놓은 것.'
- 자바에서 새로운 객체를 생성하는 방법은 다음과 같다.
- 클래스명 변수명;
- 변수명 = new 클래스명();
- 위 문장은 클래스명 변수명 = new 클래스명(); 과 같이 작성 가능하며 앞의 클래스명의 경우 인스턴스의 타입을 나타내는 것이다.
- 다음은 45개의 후보 공들 중 6개를 뽑는 로또예제이다.
- 이 예제는 45개 각각의 공들을 만들어 낼 수 있는 LottoBall클래스, 45개의 공들을 만들어 담고 그중 6개의 당첨 공을 뽑아내는 LottoMachine, LottoMachine의 객체를 생성하여 결과를 출력하는 Main클래스로 이루어져 있다.
package Lotto;
public class Main {
public static void main(String[] args) {
LottoMachine machine = new LottoMachine(); // LottoMachine객체 생성.
for (LottoBall balls : machine.selectBalls()) {// 생성된 객체에서
// selectBalls메소드를 통해
// balls배열에 결과를 넣고
System.out.println(balls.num);// 결과 출력.
}
}
}
package Lotto;
public class LottoMachine {
LottoBall[] balls; // LottoBall type의 balls배열 생성. 45개의 로또볼들을 담을 곳.
public LottoMachine() { // 45개의 공을 생성하여 balls배열에 담음.
balls = new LottoBall[45];
for (int i = 1; i <= 45; i++) {
balls[i - 1] = new LottoBall(i);
}
}
public LottoBall[] selectBalls() { // 6개의 당첨공을 랜덤함수로 뽑고 중복을 방지하기 위해 ball이
// 선택되었던 공인지 확인함.
LottoBall[] resultBalls = new LottoBall[6];
for (int i = 0; i < 6; i++) {
int index = (int) (Math.random() * balls.length);
LottoBall ball = balls[index];
if (ball.isSelected()) {
i--;
continue;
}
resultBalls[i] = ball; // 선택되었던 공이 아닐경우 결과 배열에 그 공을 담음.
}// end for
return resultBalls;
}
}
package Lotto;
public class LottoBall {
int num; // 공의 번호
boolean selected; // 중복당첨 방지를 위한 선택되었던 공인지 아닌지 판별 boolean 변수
public LottoBall(int num) { // 생성될때 공은 자신의 번호를 반드시 가지고 있어야 하므로 생성자 생성.
super();
this.num = num;
}
public boolean isSelected() { // 공 자기자신이 선택되었던 공인지 아닌지를 알고 있음.
boolean result = false;
if (selected == false) {
result = false;
selected = true;
} else {
result = true;
}
return result;
}
}
- 다음은 도넛의 면적을 구하는 예제이며 도넛의 바깥원의 넓이에서 안쪽 구멍부분의 넓이를 빼줌으로써 결과를 구하게 된다.
- 이 예제는 바깥 원과 안쪽 원 객체를 각각 생성할 수 있는 Circle클래스, 생성된 원들의 넓이의 차를 구해 결과적으로 도넛의 넓이를 계산하는 CircleManager클래스, 사용자로부터 바깥 원과 안쪽 원의 반지름을 입력받고 결과를 출력하는 CircleUI클래스, Main클래스로 구성되어있다.
- 본 예제에서 흥미있는 부분은 각 원들의 넓이를 Circle클래스에서 구한다는 점인데 이는 각 원들이 자기 자신의 반지름 뿐만이 아니라 넓이도 가장 잘 알고있다는 사실을 반영한 것이다. 보통 원의 넓이를 구하는 계산은 CircleManager에서 다뤄야 할 것 같지만 조금 더 생각해보면 각각의 원들은 자신의 넓이를 다른 누구보다 자신들이 가장 잘 알고 있을테다.
package Circle;
public class Main {
public static void main(String[] args) {
CircleUI ui = new CircleUI();
ui.calcResult();
}
}
package Circle;
import java.util.Scanner;
public class CircleUI {
CircleManager manager;
Scanner scanner;
public CircleUI() {
manager = new CircleManager();
scanner = new Scanner(System.in);
}
public void calcResult() {
System.out.println("outer");
Double outer = Double.parseDouble(scanner.nextLine()); // 바깥 원의 반지름
// 입력받음.
System.out.println("inner");
Double inner = Double.parseDouble(scanner.nextLine()); // 안쪽 원의 반지름
// 입력받음.
Double result = manager.calcDonutArea(new Circle(outer), new Circle(inner));
System.out.println(result);// 입력받은 반지름으로 결과출력.
}
}
package Circle;
public class CircleManager {
public double calcDonutArea(Circle outer, Circle inner) { // 바깥 원과 안쪽 원의 넓이를
// 받아서 차이를 통해
// 도넛의 넓이를 구함.
return outer.getArea() - inner.getArea();
}
}
package Circle;
public class Circle {
double radious; // 원의 반지름
public Circle(double radious) {
super();
this.radious = radious;
}
public double getArea() { // 반지름으로 생성될 원의 넓이를 구함. 원의 넓이는 원 객체 자신이 가장 잘 알고
// 있다!
return (this.radious * this.radious) * Math.PI;
}
}