본문 바로가기
JAVA

익명 클래스란

by 슈슈슉민 2023. 11. 23.
package anonymousclass;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public MyReadable createInstance(final int age) {
        //local inner class
        class PersonWithAge implements MyReadable {

            @Override
            public void readInfo() {
                System.out.println("이름 : " + name);
                System.out.println("나이 : " + age);
            }
        }

        MyReadable person = new PersonWithAge(); // 다형성
        return person;
    }

}

interface MyReadable {
    public abstract void readInfo();
}

 

이것을 main에서 호출한다면 아래와 같이 작성 할 수 있다.

package anonymousclass;

public class LocalMain {
    public static void main(String[] args) {
        Person person = new Person("ABC");

        MyReadable r = person.createInstance(23);
        r.readInfo();
    }
}

 

자바에서는 메소드 내에 곧바로 메소드를 만들 수 없다. 자바는 순수 객체지향이기 때문에 모든 것이 class로 되어있어야한다. 클래스{메소드{클래스{메소드}}} 이런 식으로 해야한다. 하지만 단지 메소드를 위한 클래스이기 때문데 클래스의 명칭이 중요한가 싶다. 

 

1. 여기서 반환값은 interface이다.

2. interface 자체로는 구체적인 구현을 제공하지 않는다(interface 는 메서드의 선언과 추상 메서드의 시그니처만을 포합한다.)

3. 따라서 interface의 객체화하는 의미가 없다. 

4. 그러므로 interface는 다른 클래스에서 구현되어야한다.(바이러스처럼ㅎ)

 

근데 아래와 같은 것이 가능하다. 모순적이다. 하지만 비하이드 스토리가 있다.

-> new interface () {메소드 구현}을 하는 순간 내부적으로 익명클래스가 만들어진다.

 

package anonymousclass;

public class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public MyReadable createInstance(final int age) {
        return new MyReadable() {
            @Override
            public void readInfo() {
                System.out.println("이름: " + name);
                System.out.println("나이: " + age);
            }
        };
    }

}

interface MyReadable {
    public abstract void readInfo();
}

 

아래는 main클래스에서 interface를 사용한 다른 예시이다.

package anonymousclass;

public class LocalMain {
    public static void main(String[] args) {
        Person person = new Person("ABC");

        MyReadable r = person.createInstance(23);
        r.readInfo();

        System.out.println();
        // 다른 class에서 interface 호출
        MyReadable m = new MyReadable() {
            int a = 10;

            @Override
            public void readInfo() {
                System.out.println(a);
            }
        };

        m.readInfo();
    }
}

 

여시서 아까와 같은 이이제기를 할 수 있다. '근데... 객체화 할 때 저 변수(m)도 큰 의미 있는 건 아니지 않아?' 맞다 m 은 그냥 매개체이다. 그 알맹이 new MyR... 자체가 객체인 것이다. 그럼 객체를 바로 호출할 수 있다는 것이다. 아래처럼!

 

new MyReadable() {

            int a = 1000;

            @Override
            public void readInfo() {
                System.out.println(a + 1000);
            }
        }.readInfo();

 

추가로 이런 구문이 interface에서만 국한 된것이 아니다. 어떤 class에서도 다 가능하다.

	.
	.
	.
System.out.println(new Myclass().methodA(20));
    }
}// end class
class Myclass{

    int a = 10;
    int b = 20;

    int methodA(int c){
        return a + b + c;
    }

}// enc class

 

이런식으로 말이다.

근데 이러한 함수의 내용을 변경하고 싶을 때가 있을 수 있다. 그럴 때 쓰라고 있는 것이 바로 override이다. 

 

	.
	.
	.
	System.out.println(new Myclass() {
            int d = 4000;

            @Override
            int methodA(int c) {
                return a + b + c + d;
            }
        }.methodA(30));
    }
}// end class
class Myclass{

    int a = 10;
    int b = 20;

    int methodA(int c){
        return a + b + c;
    }

}// enc class

 

'JAVA' 카테고리의 다른 글

MultiThread란? + Lock 사용 방법  (0) 2024.06.20
람다란  (0) 2023.11.23