지난밤에 잘려고 누웠다가 뜬금없는 생각이 들었다.

Interface를 구현한 Class에서 같은 이름의 변수를 재정의 하면 어찌될까?

원래 알았던거 같은데, 긴가민가한 문제 ^^;;




Interface 하나와 그를 구현한 Class 하나를 만들고 테스트 해보았다.

먼저 작성한 Interface와 Class

interface INagarryInterface

{

    String I_NAME = "ITestInterface";

    String GetClassName();

}


class NagarryClass implements INagarryInterface

{

    public static final String I_NAME = "TESTClass";

    public String GetClassName()

    {

       return I_NAME;

    }

}


interface와 class모두 맴버로 I_NAME이란 변수와 GetClassName이라는 함수가 정의 되어있다.

그럼 이를 사용해서 아래와 같이 실험해보자

public class AppMain

{

    public static void main(String[] args)

    {

        System.out.println(INagarryInterface.I_NAME); //(1)

        System.out.println(NagarryClass.I_NAME); //(2)

        

        INagarryInterface test1 = new NagarryClass();

        System.out.println(test1.I_NAME); //(3)

        System.out.println(test1.GetClassName()); //(4)

        

        NagarryClass test2 = new NagarryClass();

        System.out.println(test2.I_NAME); //(5)

        System.out.println(test2.GetClassName()); //(6)

    }

}



총6번의 출력이 있다.

(1)번의 출력결과야 보나마나

ITestInterface

이고, (2)번 출력결과야 보나마나

TestClass일 것 이다.


결과값은 다음과 같다.

ITestInterface

TESTClass

ITestInterface

TESTClass

TESTClass

TESTClass



(3)번과 (4)번의 출력결과가 재미지다.

똑같은 test1이라는 객체를 이용해서 I_NAME 변수를 출력한것인데,

결과가 다르니 말이다.


(3)번의 이유는 이렇다.

INagarryInterface test1 = new NagarryClass();

이라고 선언했으니....

test1은 NagarryClass의 Heap메모리를 갖게되지만,

엄연히 INagarryInterface타입이다.


I_NAME 변수는 인터페이스나 클래스에서 static으로 정의 되어있다.

(인터페이스의 변수는 무조껀 public static final이다. public static final을 명시하든 하지않든 말이다.) 

test1이 인스턴스 객체이지만, I_NAME은 Heap영역에 있는 것이 아니라,

static 데이터 영역에 있다.

따라서 test1의 I_NAME에 접근하게 되면 NagarryClass이 아닌

INagarryInterface에 접근하게 되는 것이다.

test1는 INagarryInterface타입이니 말이다.


(4)번의 이유는 반대로...

test1의 함수 GetClassName()를 이용하여 I_NAME 변수에 접근했는데,

이 함수는 Heap영역에 있고, 이건 명시적인 NagarryClass에 접근하게 되는것이다.

따라서 이 함수안에서 접근한 I_NAME는 INagarryInterface의 데이터 영역이 아니라 아니라 NagarryClass영역이다.



결과 인증샷



Google AdSense

+ Recent posts