티스토리 뷰

LANGUAGE/JAVA

[JAVA] ANONYMOUS OBJECT - 익명 객체

진심스테이크 2018. 6. 28. 11:30

 

Anonymous (익명) : 이름이 없는 객체

- 단독으로 생성할 수 없고, 클래스를 상속하거나 인터페이스를 구현해야만 생성가능

- 필드의 초기값이나 로컬변수의 초기값, 매개 변수의 매개값으로 주로 대입됨

 

1. 자식 객체 생성

- 부모 타입으로 필드나 변수를 선언하고, 자식 객체를 초기값으로 대입할 경우

- 생성자 선언 불가

class Child extends Parent { } //자식 클래스 선언

class A {
    Parent field = new Child(); //필드에 자식 객체를 대입
    void method() {
        Parent localVar = new Child(); //로컬 변수에 자식 객체를 대입
    }
}

 

-> 필드를 선언할 때 초기값으로 익명 자식 객체를 생성해서 대입

class A{
    //A 클래스의 필드 선언
    Parent field = new Parent() {
        int childField;
        void childMethod() { }
        
        //Parent의 메소드를 오버라이딩
        @Override
        void parentMethod() { }
    };
}

 

-> 메소드 내에서 로컬 변수를 선언할 때 초기값으로 익명 자식 객체를 생성해서 대입

class A{
    void method() {
        //로컬 변수 선언
        Parent localVar = new Parent() {
            int childField;
            void childMethod() { }
            
            //Parent 메소드를 오버라이딩
            @Override
            void parentMethod() { }
        };
    }
}

 

-> 메소드의 매개 변수가 부모 타입일 경우, 메소드 호출 코드에서 익명 자식 객체를 생성해서 매개값으로 대입 가능

class A{
    void method1(Parent parent) { }
    void method2() {
        //method1() 메소드 호출
        method1(
                //method1() 매게값으로 익명 자식 객체를 대입
                new Parent() {
                    int childField;
                    void childMethod() { }
                    @Override
                    void parentMethod() { }
                }
            );
    }
}

 

- 익명 자식 객체에 새롭게 정의된 필드와 메소드는 익명 자식 객체 내부에서만 사용됙, 외부에서는 필드와 메소드에 접근 불가

   -> 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용가능하기 때문

public class Person {
    void wake() {
        System.out.println("7시에 일어납니다");
    }
}

 

 

예시

public class Anonymous {
    // 필드 초기값으로 대입
    // 필드 선언과 초기값 대입
    Person field = new Person() {
        void work() {
            System.out.println("출근합니다");
        }

        @Override
        void wake() {
            System.out.println("6시에 일어납니다");
            work();
        }
    };

    void method1() {
        // 로컬 변수값으로 대입
        // 로컬 변수 선언과 초기값 대입
        Person localVar = new Person() {
            void walk() {
                System.out.println("산책합니다");
            }

            @Override
            void wake() {
                System.out.println("7시에 일어납니다");
                walk();
            }
        };

        // 로컬 변수 사용
        localVar.wake();
    }

    void method2(Person person) {
        person.wake();
    }
}
public class AnonymousEx {
    public static void main(String[] args) {
        Anonymous anony = new Anonymous();
        
        //익명 객체 필드 사용
        anony.field.wake();
        
        //익명 객체 로컬 변수 사용
        anony.method1();
        
        //익명 객체 매개값 사용
        anony.method2(
                //매개값
                new Person () {
                    void study() {
                        System.out.println("공부합니다");
                    }
                    
                    @Override
                    void wake() {
                        System.out.println("8시에 일어납니다");
                        study();
                    }
        });
    }
}

 

 

2. 익명 구현 객체 생성

- 인터페이스 타입으로 필드나 변수를 선언하고, 구현 객체를 초기값으로 대입하는 경우

- 구현 클래스 선언 후, new 연산자를 이용해서 구현 객체를 생성한 후, 필드나 로컬 변수에 대입

- 모든 추상 메소드들의 실체 메소드를 작성해야 함

- 필드와 메소드를 선언 가능하지만 실체 메소드에서만 사용가능하고 외부에서는 사용 불가

class TV implements RemoteControl{ }

class A {
    RemoteControl field = new TV(); //필드에 구현 객체를 대입
    void method() {
        RemoteControl localVar = new TV(); //로컬 변수에 구현 객체를 대입
    }
}

 

-> 필드를 선언할 때 초기값으로 익명 구현 객체를 생성해서 대입

class A {
    //class A의 필드 선언
    RemoteControl field = new RemoteControl() {
        @Override
        //RemoteControl 인터페이스의 추상 메소드에 대한 실체 메소드
        void turnOn() { }
    }
}

 

-> 메소드 내에서 로컬 변수를 선언할 때, 초기값으로 익명 구현 객체를 생성해서 대입

void method() {
    //로컬 변수 선언
    RemoteControl localVar = new RemoteControl() {
        @Override
        //RemoteControl 인터페이스의 추상 메소드에 대한 실체 메소드
        void turnOn() { }
    }; 
}

 

-> 메소드의 매개 변수가 인터페이스 타입일 경우, 메소드 호출 코드에서 익명 구현 객체를 생성해서 매개값으로 대입

class A{
    void method1(RemoteControl rc) { }
    
    void method2() {
        //method1() 메소드 호출
        method1(
                new RemoteControl() {
                    @Override
                    //method1()의 매개값으로 익명 구현 객체를 대입
                    void turnOn() { }
                }
            );
    }
}

 

예시

public interface RemoteControl {
    public void turnOn();
    public void turnOff();
}
public class Anonymous {
    //필드 초기값으로 대입
    //필드 선언과 초기값 대입
    RemoteControl field = new RemoteControl() {
        @Override
        public void turnOn() {
            System.out.println("TV를 켭니다");
        }
        
        @Override
        public void turnOff() {
            System.out.println("TV를 끕니다");
        }
    };
    
    void method1() {
        //로컬 변수값으로 대입
        //로컬 변수 선언과 초기값 대입
        RemoteControl localVar = new RemoteControl() {
            @Override
            public void turnOn() {
                System.out.println("Audio를 켭니다");
            }
            
            @Override
            public void turnOff() {
                System.out.println("Audio를 끕니다");
            }
        };
        
        //로컬 변수 사용
        localVar.turnOn();
    }
    
    void method2(RemoteControl rc) {
        rc.turnOn();
    }
}
public class AnonymousEx {
    public static void main(String[] args) {
        Anonymous anony = new Anonymous();

        // 익명 객체 필드 사용
        anony.field.turnOn();

        // 익명 객체 로컬 변수 사용
        anony.method1();

        // 익명 객체 매개값 사용
        anony.method2(
                // 매개값
                new RemoteControl() {
                    @Override
                    public void turnOn() {
                        System.out.println("SmartTV를 켭니다");
                    }

                    @Override
                    public void turnOff() {
                        System.out.println("SmartTV를 끕니다");
                    }
                });
    }
}

 

 

3. 익명 객체의 로컬 변수 사용

- 익명 객체 내부에서는 바깥 클래스의 필드나 메소드는 제한 없이 사용할 수 있음

- 매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 익명 객체에서 사용할 수 없게 됨 -> final 선언

- 익명 객체에서 사용된 매개 변수와 로컬 변수는 모두 final 특성을 갖음

public interface Calculatable {
    public int sum();
}
public class Anonymous {
    private int field;
    public void method(final int arg1, int arg2) {
        final int var1 = 0;
        int var2 = 0;
        
        field = 10;
        
        //arg1 = 20;
        //arg2 = 20;
        
        //var1 = 30;
        //var2 = 30;
        
        Calculatable calc = new Calculatable() {
            @Override
            public int sum() {
                int result = field + arg1 + arg2 + var1 + var2;
                return result;
            }
        };
        
        System.out.println(calc.sum());
    }
}
 
public class AnonymousEx {
    public static void main(String[] args) {
        Anonymous anony = new Anonymous();
        anony.method(0, 0);
    }
}

 

 

 

'LANGUAGE > JAVA' 카테고리의 다른 글

[JAVA] ANONYMOUS - 익명  (0) 2019.07.16
[JAVA] 삼항연산자  (0) 2019.07.12
[JAVA] 중첩 클래스  (0) 2018.06.27
[JAVA] ECLIPSE 단축키  (0) 2018.04.15
[JAVA] 경로  (0) 2018.04.15
댓글