본문 바로가기

Developer/Java-oop

#003. Class 와 Instance...

#003. Class 와 Instance...

 

1. 객체지향프로그래밍 [object-oriented programming ] | 네이버 백과사전

모든 데이터를 오브젝트(object;물체)로 취급하여 프로그래밍 하는 방법으로, 처리 요구를 받은 객체가 자기 자신의 안에 있는 내용을 가지고 처리하는 방식이다.

 

2. 클래스(class) 는 변수와 메서드로 이루어진다. 변수는 데이타를 담는 용도로 사용하고, 메서드는 기능을 담는 용도로 사용한다.

 

3. #001강좌를 참고해서 oop 패키지와 그 안에 클래스 Person 을 만들어본다. 그러면 아래와 같은 화면이 나올 것이다.

 

4. Person의 클래스에는 사람의 이름, 나이, 성별을 담을 수 있는 변수와 사람의 정보를 출력할 수 있는 메서드를 만들어 보자. 아래와 같이 코딩을 한다.

아래코드가 작성이 다 되면 저장을 해보자, 상단에 디스켓 모양을 누르거나 Ctrl+S를 누르면 된다.

eclipse의 workspace가 "D:\java\workspace" 라면, 아래의 두 개의 파일이 생성되는 것을 볼 수 있다. 저장하면 자동으로 컴파일이 된다는 걸 알 수 있다.

D:\java\workspace\study\src\oop\Person.java (소스코드-사람언어)

D:\java\workspace\study\bin\oop\Person.class (중간코드-자바어)

컴파일이 완료되었다면 다른 클래스에서 객체를 생성할 수 있다.

코드

package oop;

public class Person {

    public String name;

    public int age;

    public char sex;

 

    public void view() {

        System.out.println("이름:" + name + ", 나이:" + age + ", 성별:" + sex);

    }

}

설명

문장3,4,5: 변수 name, age, sex 는 멤버변수 또는 인스턴스변수 라도 불린다.

문장7: 멤버메서드 라고 불린다.

 

5. 새로운 class 파일 PersonTest 를 만들어 앞에서 만든 Person.class 파일을 이용해 객체를 만들어 사용해 보자.

코드

package oop;

public class PersonTest {

    public static void main(String[] args) {

        Person p1 = new Person();

        p1.name = "김동혁";

        p1.age = 2;

        p1.sex = 'M';

        Person p2 = new Person();

        p2.name = "이연희";

        p2.age = 24;

        p2.sex = 'F';

        p1.view();

        p2.view();

    }

}

결과

이름:김동혁, 나이:2, 성별:M

이름:이연희, 나이:24, 성별:F

설명

문장4: 앞에서 만든 Person 의 클래스 명을 써주고, 사용 할 객체(instance) 명을 선언하고, new 예약어를 사용해서 만들어준다. p1 객체는 Person의 모든 멤버와 메서드를 똑같이 복사를 하게 된다.

문장5,6,7: p1의 복사된 공간에 멤버변수에 값을 지정해준다.

문장8: p2 도 Person 클래스의 객체로 생성된다.

문장9,10,11: p2의 복사된 공간에 멤버변수에 값을 지정해준다.

문장12,13: p1,p2의 복사된 공간에 멤버메서드의 기능을 호출한다. (실제로 메서드는 따로 만들지 않는다고 한다.)

 

6. 위에 작성해서 테스트 했던 코드에 몇 가지 더 붙여서 테스트를 해보겠다.

코드

package oop;

public class PersonTest {

    public static void main(String[] args) {

        Person p1 = new Person();

        p1.name = "김동혁";    p1.age = 2; p1.sex = 'M';

        Person p2 = new Person();

        p1.view();    p2.view();        //출력1,2

        System.out.println(p1.hashCode());        //출력3

        System.out.println(p2.hashCode());        //출력4

        p2 = p1;

        p1.view();    p2.view();        //출력5,6

        System.out.println(p1.hashCode());        //출력7

        System.out.println(p2.hashCode());        //출력8

        p2.name = "이연희";    p2.age = 24; p2.sex = 'F';

        p1.view();    p2.view();        //출력9,10

    }

}

결과

이름:김동혁, 나이:2, 성별:M

이름:null, 나이:0, 성별:

1414159026

1569228633

이름:김동혁, 나이:2, 성별:M

이름:김동혁, 나이:2, 성별:M

1414159026

1414159026

이름:이연희, 나이:24, 성별:F

이름:이연희, 나이:24, 성별:F

설명

문장7 까지와 결과2 까지는 상단에 있던 테스트 결과였다.

문장8: p1.hashCode() 의 의미는 객체의 참조 값(고유번호)을 의미하지만, 실제 메모리 주소는 아니다.(절대 java에서는 메모리 주소를 알 수 없다.)

문장8,9: 결과3,4 p1과 p2의 참조 가 다른 것을 알 수 있다.

문장10: p2 = p1 는 p1의 참조 값을 p2 로 복사하라는 의미이다. 이때 p2가 가지고 있던 참조 값의 메모리는 garbage가 발생된다. JVM이 garbage collector 를 주기적으로 실행하여 자원을 반환한다.

문장11: 출력5,6 p1과 p2의 결과 값이 같은 것을 확인할 수 있다.

문장12,13: 출력7,8 p2의 참조 값이 p1과 같아진 것을 확인할 수 있다.

문장14: p2의 데이터를 새롭게 변경한다.

문장15: 출력9,10 p1의 결과도 함께 변경된 것을 확인할 수 있다. (실제로 p2의 값을 변경할 때 같은 곳을 가리키고 있기 때문에 같이 변경된 것처럼 보인다.)

* 여기서 중요한 것은 객체는 = (대입연산)을 할 때 데이터를 복사하는 것이 아니라, 참조 값을 복사하는 것을 알 수 있다.

 

7. 위 내용을 보고 JVM이 메모리에 어떻게 할당하는지 확인해 보자.

명령어

클래스 영역

[static 영역]

(같은클래스1번)

메서드 영역(변수)

[stack 영역]

(heap영역을 참조)

객체 영역

[heap 영역]

(실제데이터공간)

Person p1 = new Person();

Person.class

p1

 

 

* 오른쪽의 주소를 참조만 한다.

person (p1)

name="김동혁"

age=2

sex='M'

view()

Person p2 = new Person();

* 이미 로드되어있음.

p2

 

 

* 오른쪽의 주소를 참조만 한다.

person (p2)

name="이연희"

age=24

sex='F'

view()

 

다음시간엔 멤버변수(instance변수) 와 static변수(class변수) 에 대해서 알아보자.

오늘 하루도 고생했네요.. 휴==33