[Java #2] Python vs Java 인스턴스 변수 접근 방법


1. 인스턴스 변수 접근 방법, 파이썬에서는?

자바를 처음 배우면서 클래스에서 정말 간단한 문제 하나로 혼란을 겪었다.

바로 this, 파이썬에서는 self로 사용되는 인스턴스 자기자신을 가르키는 명령어 때문이었다.

파이썬에서는 self를 사용하지 않으면 인스턴스 객체의 변수에 접근할 수 없다.

파이썬 예시 코드를 보자.

class Person:

    name = "what"
    age = 0

    def __init__(self, n, a):
        name = n
        age = a

    def setAge(self, a):
        self.age = a
        age = a * 2

    def setName(self, name):
        self.name = name

    def print(self):
        print(self.name, self.age)


kim = Person("kim", 24)
kim.print()   # what 0
kim.setAge(25)
kim.print()   # what 25
kim.setName("park")
kim.print()   # park 25

위 예시의 파이썬 코드에서 초기화를 통해 name에 “kim”, age에 24를 전달하였으나 초기의 what과 0이 출력된다.

또한 setAge 메소드에서 25의 값을 전달하였고,

self.age = 25
age = 25*2

코드가 실행이 됐을 것이지만 결과는 25로, self 를 이용하여 접근한 코드만 제대로 동작하였다.

위의 예시처럼, 파이썬의 클래스에서 인스턴스 변수에 접근하려면 self를 필수적으로 사용해주어야한다.


2. 자바에서의 인스턴스 변수(field) 접근과 this의 의미

파이썬의 self와 같이, 자바에서는 this를 통해 인스턴스 변수(자바에서는 필드라고 부르는 듯하다)에 접근이 가능하다.

하지만 이것이 반드시 필수적으로 요구되지는 않더라.

자바의 예시코드이다.


public class Person {
	private String name;
	private int age;

	public Person(String n, int a) {
		name = n;
		age = a;
	}

	public void setAge(int age) {
		age = age;
	}

	public void setName(String n) {
		this.name = n;
	}

	public void print() {
		System.out.printf("%s %d  %n", name, age);
	}

	public static void main(String[] args) {
		Person kim = new Person("kim", 24);
		kim.print(); // kim 24
		kim.setAge(25);
		kim.print(); // kim 24
		kim.setName("park");
		kim.print(); // park 24
	}
}

파이썬 코드와 거의 유사한 코드이지만, 실행 결과는 전혀 다르다.

초기화 메소드에서는 this 없이 접근하였고, setName 메소드에서는 this를 통해 접근하였다.

하지만 두 코드 모드 제대로 동작하여 초기화 시 전달한 “kim”과 24가 제대로 동작하여 초기화 되었으며, setName 메소드를 통해 이름을 “park”으로 변경하였다.

그러면 this는 무슨 의미일까? 사용하지 않아도, 사용해도 동일한 결과를 출력해준다면 코드가 간결해지도록 사용하지 않는 것이 좋지 않을 것 같다.

하지만 코드를 다시 보면 문제가 하나 있다.

setAge를 통해 전달한 25의 나이가 제대로 동작되지 않아, 마지막까지 나이를 24로 출력하고 있다.

코드를 다시 보자.

public void setAge(int age) {
    age = age;
}

말도 안되는 문장이다.

도대체 여기서의 age는 전달된 파라미터를 가르키는 걸까? 아니면 인스턴스 필드를 가르키는 걸까?

어느 것을 가르키든 간에 결국 아무 동작도 일어나지 않는다.

이 때 this를 이용하면 코드가 제대로 동작한다.

public void setAge(int age) {
    this.age = age;
}

this는 이처럼 파라미터와 필드의 변수명이 겹칠 때, 어느 것을 말하는 것인지 명시하기 위해 사용된다. 사실, 코드가 길어졌을 때의 복잡한 상황에서 오류를 방지하기 위해 명시적으로 항상 this를 사용하는 것이 나을 듯하다.

처음에는 왜 this를 어느 코드에서는 사용했다가, 다음 페이지에서 다시 없어지고 다시 나타나고 반복하는지 이해가 되지 않았다…


3. 상속 시에 필드 명이 겹치면 어떻게 될까?

extends를 통해 클래스를 상속하였을 때 부모 클래스와 자식 클래스가 동일한 이름을 가진 필드가 존재할 때, this를 사용하지 않으면 어떤 변수를 가르킬까?

궁금해서 찾아보고 실행해 본 결과, 자식 클래스의 필드 명을 가르키더라.

찾아보니 상속 시에 동일한 필드를 가지면 부모 클래스의 필드가 은닉(hide)된다고 한다.

[Java #1] 플랫폼 독립성




© 2018. by YH

Powered by YH KIM