ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] 익명 클래스
    java/Class.Interface.Method 2021. 8. 28. 14:54

    -익명 클래스란

     

    class A 를 상속받아 어떠한 기능을 하는 class B를 만들어야 한다고 가정하자.

    class B extends A로 클래스 B를 선언한 뒤에  new B를 통해 객체를 생성한다.

    만약 프로그램에서 클래스 B는 현재 한번만 사용되고 차후에 사용될 필요가 없다면??

    클래스로 선언해 놓을 필요가 없을 것이다.

     

    익명 클래스는 기존의 방식처럼 클래스를 선언하지 않고 코드상에서 한번쓰는 방식으로 선언할 수 있다.

    또한 이름을 가지지 않는다. 

     

    익명 클래스는 인터페이스 하나만 구현하거나, 클래스 하나만 상속받을 수 있다.

    여러 인터페이스 동시에 구현 불가

    인터페이스 구현, 클래스 상속이 동시에 불가

    하나를 상속받거나, 구현해야하기 때문에 아무것도 상속받지 않거나, 아무것도 구현하지 않은 마음대로 만들고 싶은 익명객체는 생성할 수 없다.


    -익명 클래스의 이름이 지어지는 법

     

    anonymous는 패키지 이름으로 헷갈리지 말자.

    익명 클래스->  외부클래스$1, 외부클래스$2

    AnonymousTest클래스의 inner class로 $1, $2와 같은 방식으로 만들어지고 있다.


    -일반적인 클래스 인스턴스 생성

     

    이름이 TestClass인 객체이다.


    - 클래스를 상속한 익명 객체

     

    1. 일반 클래스를 상속한 익명 객체, 일반 클래스의 메서드를 오버라이딩한 익명 객체

    AnonymousTest의 inner class로 이름이 없고 $1,$2와 같은 방식으로 만들어졌다.

     

     

    2. 추상 클래스를 상속하여 추상 메서드를 구현한 익명 객체

     


    - 인터페이스를 구현한 익명 객체

    인터페이스를 구현한 익명 객체 생성시 클래스처럼 new TestInterface(){ .....}

    생성자 인자를 넣어주듯이 ()를 붙여준다.

    인터페이스는 생성자가 없지만 익명 클래스 문법으로 인해 new 인터페이스() { 내용 } 의 ( )를 넣어줘야 한다.


    추상 클래스,클래스를 상속한 익명 클래스 익명 객체를 만드는 위의 테스트 코드에서는 생성자가 기본으로 () 였다.

    생성자가 있는 클래스를 상속받은 익명 객체를 만들때는 ()에 생성자 인자를 넣어주면 된다.


    -익명 클래스의 메서드

     

    up캐스팅과 down캐스팅의 개념을 잠깐 확인하자

    up-casting 이 되어있어 부모의 참조변수로는 자식의 멤버를 사용하지 못한다.

    instanceof연산자로 인스턴스의 타입을 체크하여 down- casting을 진행하여 자식의 멤버를 사용할 수 있다.

     

    위의 예제에서 Child라는 클래스가 선언되어 있어 Child타입으로 down-casting이 가능하지만 

    익명 객체의 경우에는 클래스를 선언하지 않고 일회용으로 사용하기 때문에 down-casting이 불가능하다.

     

    그렇기 때문에 익명 클래스에서만 독자적으로 정의된 메서드를 사용하는 경우에는

    .인 dot notation으로는 자기 자신을 통해서는 사용할 수 있지만 

    익명 객체가 조상 참조변수로 참조되는 경우에는 독자적으로 정의된 메서드를 사용할 수 없다.


    -Java 익명 클래스의 한계

     

    kotlin의 object에 대해서 다시금 복습 하는 겸 자바 익명 클래스 글을 보다가 추가한 내용이다.

    궁금증은 kotlin의 object expression로부터 시작되었다. 이 궁금증은 java 익명 클래스의 한계점이였다는 것과 코틀린 object expression이 얼마나 모던하게 개선된 문법인지 느껴졌다.

    java의 익명 클래스는 상속의 개념이지만 익명 객체는 항상 super type의 변수에 담길 수 밖에 없다. 실로 익명 클래스에 메서드를 선언하는데 호출할 방법이 없다는 것이다.

     

    다음의 코드를 보자.

    Parent 클래스를 상속한 익명 클래스는 독자적으로 anonymousMethod 메서드가 선언되어 있다.

    그러나 자바의 경우 익명 클래스에 해당하는 객체는 Parent 타입 변수에 담길 수 밖에 없다.

    (코틀린의 경우 익명 클래스에 해당하는 타입에 담길 수 있다)

    이러한 경우 익명 클래스에서는 Parent 타입 변수를 익명 클래스 타입으로 down casting 할 수 있는 방법이 없어서 anonymousMethod 메서드는 선언하였어도 절대 사용할 수 없다.

    익명 클래스는 상속의 개념이라기보다  익명 클래스의 변수를 통해 조상 메서드를 재정의하는 것이 본목적이지 않나 싶다.  

     

    코틀린의 object expression

    https://hellose7.tistory.com/120

     

    [Kotlin] object

    object expression과 object declaration 1. object expression 오브젝트 표현식의 경우 자바의 익명 클래스의 개념을 + 코틀린의 새로운 개념이다. [Java/Class] - [Java] 익명 클래스 익명 클래스란 실제로 클래..

    hellose7.tistory.com

     

     

     

    댓글

Designed by Tistory.