지난시간(Hello, World!!)은 객체지향적이지 않았습니다...
클래스를 하나만 만들고, 그 클래스의 main()메소드에서 시작해서 다른 메소드들을 탐방하며 main()메소드가 종료할 때 프로그램이 종료되는 것은, 기존의 절차적 프로그래밍과 같은 방법입니다.
이건 자바의 철학에서 벗어나는 행동이죠..
자!! 이제 클래스를 설계해 봅시다.
클래스 설계 시 기초적으로 알아 두어야 할 것은, 그 클래스가 가진 것(소유와 상태)과 할 수 있는 것(행동)을 정하는 것입니다.
만약 집에 강아지가 있다고 합시다.
이 강아지는 이름(소유한 것)과 배고픈 정도(상태)가 있습니다.
그리고 먹는 행동, 짓는 행동 등이 있습니다.
먹는 행동은 배고픈 정도에 먹기도 하고, 먹지 않기도 하며,
짓는 행동은 배고픈 정도에 따라 그 소리가 달라지기도 합니다.
그럼 위의 기초자료를 가지고 클래스를 만들어 봅시다.
ClassName : MyPuppy
가진 것 : name, hungry
할수 있는 것 : eat(), bark()
가진 것으로 멤버 변수를 만들고, 할 수 있는 것으로 메소드를 만드시면 됩니다..
MyPuppy.java
-
public class MyPuppy{
-
// 인스턴스 변수를 만드는 곳..
-
String name; // 이름 – 가지고 있는 것
-
int hungry; // 상태 – 객체의 행동을 좌우하는 것..
-
-
// 메소드들을 만드는 곳..(사실 위치는 크게 상관없습니다..)
-
public void eat(){
-
if(hungry <= 70){
-
hungry = hungry + 30;
-
System.out.println(“냠냠 : 배고픈정도 - ” + hungry);
-
} else {
-
System.out.println(“배고프지 않아요!!”);
-
}
-
}
-
-
public void bark(){
-
if(hungry <= 30)
-
{
-
System.out.println("낑낑~~ : 배고픈정도 - " + hungry);
-
}else if(hungry <= 70){
-
System.out.println("멍멍~~ : 배고픈정도 - " + hungry);
-
}else{
-
System.out.println("왕왕~~ : 배고픈정도 - " + hungry);
-
}
-
hungry = hungry – 10;
-
}
-
}
이렇게 name과 hungry를 멤버변수로 갖고, eat(), bark()를 메소드로 갖는 MyPuppy라는 클래스를 다 만들었습니다.
그런데... 클래스를 만드는 것만으로 무언가를 할 수 있을까요?
아닙니다.
그 클래스를 사용할 수 있는 인스턴스(객체)를 만들어야겠지요??
위의 클래스를 가지고 무언가를 할 수 있는 테스터 클래스를 만들어서 시험하겠습니다.
MyPuppyTest.java
-
public class MyPuppyTest{
-
publc static void main(String[] args){
-
MyPuppy blackdol;
-
blackdol = new MyPuppy();
-
blackdol.name = “GGamdol”;
-
blackdol.hungry = 100; // MyPuppy객체를 만든후 세팅 그리고 메소드 호출...
-
blackdol.bark();
-
blackdol.bark();
-
blackdol.bark();
-
blackdol.eat();
-
blackdol.bark();
-
blackdol.bark();
-
blackdol.bark();
-
blackdol.eat();
-
}
-
}
자!! 봅시다!!
명령행 인자에서 java MyPuppyTest를 실행하면 MyPuppyTest클래스의 main()메소드를 실행합니다.
MyPuppyTest의 인스턴스는 생기지 않습니다.
첫 시간에 한번 언급했던 정적메소드이기 때문이지요.. (정적메서드에 대해서는 나중에 알아봅시다.. 시간 나면.. 서두르지 마세요!! 다~ 합니다..)
main()메소드가 실행되면,
Line 3. 에서 blackdol 이라는 MyPuppy클래스를 가질 수 있는 변수(지역변수, 로컬변수, 스택변수, 혹은 인스턴스변수라고들 부릅니다. 뭐라고 불러도 상관없습니다..)가 생겨납니다...이건 스택영역에 생겨납니다.
이 변수의 크기나 값은 JVM마다 다를 수 있습니다. (C에서는 크기는 일정했었죠? JVM이 수많은 기계장치에서 똑같은 동작을 수행 할 수 있게끔 해 주는 것이므로,, 이 변수의 크기가 다르더라도 우린(프로그래머) 상관없습니다.. 제대로 동작만 할 수 있게 해 달라구요!!!)
Line 4. 에 드디어 MyPuppy클래스의 인스턴스(실제 객체)가 힙(Heap)영역에 생겨나고 이 실제 인스턴스를 blackdol이라는 스택변수에 연결해 줍니다. 사실은 생겨난 MyPuppy인스턴스의 위치 값을 갖는 것이지요.(그냥 위치값이 아니라 MyPuppy형 변수입니다..ㅠㅠ 이걸 뭐라 설명해야 할지..)
Line 5. 에 이름을 정해주고.. (우리는 깜돌이라고 정했습니다._
Line 6. 에 배고픈 정도를 100으로 정해준 뒤...
Line 7. 부터 인스턴스변수(blackdol)를 이용하여 MyPuppy클래스의 기능을 사용하였습니다.
스택변수는 메소드내(블록영역내)에서만 살아있는 것이지만, 인스턴스는 힙영역에서 그 인스턴스를 참조하는 것이 없을 때 까지 살아남을 수 있습니다. (예전 c에서는 이 힙영역의 메모리를 해제해 주지 않아 자꾸 문제를 일으켰었죠.. JAVA에서는 걱정하지 마세요!! 자바라는 언어가 가지고 있는 가비지콜렉션 기능에 의해 더이상 참조되지 않는 객체들은 자동으로 메모리 해제를 시켜줍니다.. 우린?? 편하죠...)
[class] [인스턴스 변수] [실제 인스턴스 혹은 객체]
클래스는 인스턴스들의 청사진, 모델 정도로 볼 수 있습니다. (클래스 정의)
인스턴스 변수는 실제 인스턴스를 제어할 수 있는 변수입니다. (MyPuppy blackdol;)
인스턴스(객체)는 클래스의 실체라고 할 수 있습니다. (blackdol = new MyPuppy();)
아무튼 이번시간에야 말로, 클래스를 설계하고, 그 클래스에 대한 인스턴스를 만들고, 그 인스턴스로 무언가를 해 보았습니다. 조금은 객체지향 프로그래밍 다워졌지요? 자바라는 언어는 이런식으로 구동됩니다.
모든 것이 클래스이며, 클래스의 인스턴스(객체)의 행동과 관계로 동작합니다.
클래스가 가진 정적변수나 정적클래스를 사용하기도 하며,그 클래스의 영역 안에서 자유롭게 이용됩니다. 다른 객체가 클래스의 인스턴스를 사용할 수 있게도, 혹은 캡슐화하여 없게도 설정할 수 있으며.. 설정에 따라 객체를 생성하지 않고도 사용할 수 있게도 해 줍니다. 또한, 메모리의 배정이나 해방등은 신경쓸 필요가 없으며(JVM이 다 알아서 해 줍니다.), 문서화나 다른 클래스의 구조를 쉽게 파악할 수 있게도 해 줍니다..
자!! 천천히 갑시다.. 천천히...