[Java] 1. 내부클래스(Inner class)와 익명 클래스(Anonymous class)


내부클래스(Inner class)와 익명 클래스(Anonymous class)에 대한 설명이다.


1. 내부클래스

//외부 클래스
class A {

    //내부 클래스
    class InnerClass {

    }
}


내부 클래스 종류

인스턴스 클래스(instance class)

  • 외부 클래스의 멤버변수 선언 위치에 선언
  • 인스턴스 멤버처럼 사용

스태틱 클래스(static class)

  • 외부 클래스의 멤버변수 선언 위치에 선언
  • static 멤버처럼 사용

지역 클래스(local class)

  • 외부 클래스의 메서드나 초기화 블럭에 선언

익명 클래스(Anonymous class)

  • 클래스의 선언과 생성을 동시에 하기에 단 한번만 사용되고 오직 하나의 객체만 셍성 되는 이름이 없는 일회용 클래스이다.


class A {
    //인스턴스 클래스
    class InstanceInner {}
    //스태틱 클래스
    static class StaticInner {}
    
    A () {
        //지역 클래스
        class LocalInner {}
    }
}



2. 익명 클래스

클래스의 선언과 생성을 동시에 하기에 단 한번만 사용되고 오직 하나의 객체만 셍성 되는 이름이 없는 일회용 클래스이다.


일반적인 방식

abstract class UsedOnce {
    public abstract void method();
}

class UsedMany extends UsedOnce {

    @Override
    public void method() {
        System.out.println("UsedMany !");
    }
}

public class ExClassType {

    public static void main (String... args) {
        //일반적인 상속 방식
        UsedMany usedMany = new UsedMany();
        usedMany.method();
    }
}



익명 클래스 방식

상속받은 익명클래스를 만들어서 사용하면 굳이 위처럼 번거롭게 자식 클래스를 별도로 생성하지 않아도 된다. 아래와 같이 오로직 단 하나의 클래스나 인터페이스에서 상속받거나 구현해서 단 하나의 객체만 생성하는 일회용 클래스이다.

abstract class UsedOnce {
    public abstract void method();
}

public class ExClassType {

    public static void main (String... args) {

        //익명 클래스 방식
        UsedOnce usedOnce = new UsedOnce() {
            @Override
            public void method() {
                System.out.println("UsedOnce !");
            }
        };
        usedOnce.method();
    }
}



인터페이스와 다형성을 활용한 익명객체 클래스 예제

//인터페이스
interface Account {
    int calculate(int baseAmt, int calcAmt);
}

//입급, 출금 계산 클래스
class DepositWithdrawalCalc {
    private int baseAmt;
    private int calcAmt;

    public DepositWithdrawalCalc (int baseAmt, int calcAmt) {
        this.baseAmt = baseAmt;
        this.calcAmt = calcAmt;
    }

    public int calcDeposit(Account acc) {
        return acc.calculate(this.baseAmt, this.calcAmt);
    }

    public int calcWithdrawal(Account acc) {
        return acc.calculate(this.baseAmt, this.calcAmt);
    }
}

public class ExAnonymous {

    public static void main (String... args) {

        DepositWithdrawalCalc depositWithdrawalCalc = new DepositWithdrawalCalc(100000, 5000);

        //입금 처리
        int calcAmt = depositWithdrawalCalc.calcDeposit(new Account() {
            @Override
            public int calculate(int baseAmt, int calcAmt) {
                return baseAmt + calcAmt;
            }
        });
        System.out.println("# 입금 처리 후 금액 : " + calcAmt);

        depositWithdrawalCalc = new DepositWithdrawalCalc(calcAmt, 1500);

        //출금 처리
        calcAmt = depositWithdrawalCalc.calcWithdrawal(new Account() {
            @Override
            public int calculate(int baseAmt, int calcAmt) {
                return baseAmt - calcAmt;
            }
        });
        System.out.println("# 출금 처리 후 금액 : " + calcAmt);
    }
}
# 입금 처리 후 금액 : 105000
# 출금 처리 후 금액 : 103500