* 본 게시물은 이지스퍼블리싱 [Do it! 점프 투 자바] 서평단 미션 수행 및 학습 목적으로 작성하였습니다.
모든 내용, 디자인, 이미지, 편집 구성의 저작권은 이지스퍼블리싱(주)와 지은이에게 있으며
학습 목적으로 내용을 재구성하여 작성했음을 밝힙니다. 문제시 삭제하도록 하겠습니다.
객체 지향 프로그래밍
계산기에 ① '3' 입력 ② '+' 기호 입력 ③ '5'입력
순서대로 입력하면 결괏값 8이 나올 것이다.
이 말은 즉슨, 계산기는 이전에 계산한 결괏값을 항상
메모리 어딘가에 저장하고 있다는 말이다.
이걸 구현한 코드는 아래와 같다.
class Calculator {
static int result = 0;
static int add(int num) { // add 메서드는 매개 변수 num으로 받은 값을 이전에 계산한 결괏값에 더한 후 돌려주는 메서드
result += num;
return result;
}
}
// 이전에 계산한 결괎값을 유지하기 위해 result 전역변수(static 변수) 사용
public class Sample {
public static void main(String[] args) {
System.out.println(Calculator.add(3));
System.out.println(Calculator.add(5));
}
}
그런데 만일 Sample 클래스에서 2개의 계산기가 필요한 경우
Calculator 클래스 하나만으로는 결과값을 각각 유지할 수 없기 때문에
클래스를 따로 만들어야 할텐데 매번 클래스를 추가할 수는 없는 노릇이다.
그렇기 때문에 객체를 사용해 해결한다.
class Calculator {
int result = 0;
int add(int num) {
result += num;
return result;
}
}
public class Sample {
public static void main(String[] args) {
Calculator cal1 = new Calculator(); // 계산기1 객체를 생성한다.
Calculator cal2 = new Calculator(); // 계산기2 객체를 생성한다.
System.out.println(cal1.add(3));
System.out.println(cal1.add(4));
System.out.println(cal2.add(3));
System.out.println(cal2.add(7));
}
}
Calculator 클래스로 만든 별개의 계산기 cal1, cal2를 객체라고 부른다.
객체 변수
class Animal {
String name;
}
public class Sample {
public static void main(String[] args) {
Animal cat = new Animal();
}
}
Animal이라는 빈 껍데기 클래스에 String name을 선언된 변수를 객체 변수(Instance variable)라고 한다.
클래스에 의해 생성되는 것은 객체, 그리고 그 클래스에 선언된 변수는 객체 변수라고 생각하면 된다.
Animal cat = new Animal();
cat이라는 객체를 생성했다면 객체 변수인 'name'에는
System.out.println(cat.name);
다음과 같이 접근 가능하다.
class Animal {
String name;
}
// 객체변수인 name에 값을 대입하기 위해 setName() 추가
public void setName(String name) {
this.name = name;
}
}
public class Sample {
public static void main(String[] args) {
Animal cat = new Animal();
}
}
public void setName(String name) {
void는 리턴 값이 없다는 의미이기 때문에
입력으로 name이라는 문자열을 받고 출력은 없는 형태의 메서드이다.
setName 메서드를 호출할 수 있도록 main 메서드를 아래와 같이 수정했다.
package lifeCoding;
class Animal {
String name;
public void setName(String name) {
this.name = name;
}
}
public class methodClass {
public static void main(String[] args) {
Animal cat = new Animal();
cat.setName("오목이");
Animal dog = new Animal();
dog.setName("바둑이");
System.out.println(cat.name); // "오목이" 출력
System.out.println(dog.name); // "바둑이" 출력
}
}
cat.name을 출력하기 전에 setName 메서드가 먼저 호출되고
cat.name은 이제 null이 아닌 것을 확인할 수 있다.
cat 객체에는 '오목이'라는 이름을 먼저 대입하고, dog 객체에 '바둑이'라는 이름을 그 다음에 대입했다면
먼저 대입됐던 '오목이' 결과가 바뀌지 않을까 생각할 수도 있겠지만 객체 변수는 공유되지 않는다.
클래스에서 가장 중요한 부분은 객체 변수의 값이 독립적으로 유지된다는 점이다.
이 점이 바로 클래스 존재의 이유이기도 하다.
(07장에서 나오는 static을 이용하면 객체 변수를 공유하도록 만들 수 있다)
// Animal 클래스 정의
class Animal {
String name; // 동물의 이름을 저장하는 멤버 변수
// 동물의 이름을 설정하는 메서드
public void setName(String name) {
this.name = name;
}
// 동물의 이름을 반환하는 메서드
public String getName() {
return name;
}
}
public class methodClass {
public static void main(String[] args) {
// Animal 클래스의 인스턴스 생성
Animal cat = new Animal();
cat.setName("오목이"); // cat 객체의 이름을 "오목이"로 설정
Animal dog = new Animal();
dog.setName("바둑이"); // dog 객체의 이름을 "바둑이"로 설정
// 각 동물 객체의 이름 출력
System.out.println(cat.getName()); // "오목이" 출력
System.out.println(dog.getName()); // "바둑이" 출력
}
}
교재에 나와 있는 내용은 아니지만
동물의 이름을 반환하는 메서드 getName을 사용한 코드이다.
이전에 코드에서는 객체의 name 멤버 변수에 직접 접근해 이름을 가져왔지만,
getName() 메서드를 사용하면 객체의 상태 정보를 외부에 노출, 변경하지 않고 정보를 가져올 수 있다.
System.out.println(cat.name); // "오목이" 출력
System.out.println(dog.name); // "바둑이" 출력
System.out.println(cat.getName()); // "오목이" 출력
System.out.println(dog.getName()); // "바둑이" 출력
name 멤버 변수에 직접 접근해 이름을 가져오는 방법도 있겠지만,
객체 지향 프로그래밍의 원칙을 따르고 유연하면서 확장 가능한 코드를 작성하기 위해선
getName() 메서드를 활용하는 것이 권장된다.