노트코드
노트코드
노트코드

블로그 메뉴

  • 홈
  • 이력서
  • 이전 블로그
  • 글쓰기
  • 관리자페이지
  • 분류 전체보기 (57)
    • 코틀린 (2)
      • 실무 프로젝트로 배우는 Kotlin & Sprin.. (2)
    • JAVA (1)
      • 디자인패턴 (1)
      • 객체지향 5대원칙 (0)
    • SPRING (32)
      • JPA (11)
      • 스프링시큐리티 (1)
      • 스프링 (8)
      • QueryDsl (1)
      • 스프링배치 (11)
    • AZURE (0)
    • ETC (10)
      • MAVEN (0)
      • GIT (0)
      • ReMind (3)
      • Exception (1)
      • CS (6)
    • 책 (8)
      • 이것이 자바다 (8)

최근 글

최근 댓글

태그

  • 스프링
  • JPA
전체 방문자
오늘
어제
hELLO · Designed By 정상우.
노트코드

노트코드

책/이것이 자바다

[9장]중첩 클래스와 중첩 인터페이스

2022. 2. 14. 09:40

9.1 중첩 클래스와 중첩 인터페이스

  • 객체 지향 프로그램에서 클래스들은 서로 긴밀한 관계를 맺고 상호작용을 한다.
    특정 클래스와 관계를 맺을 경우에는 관계 클래스를 클래스 내부에 선언하는것이 좋다.
  • 중첩 클래스란 클래스 내부에 선언한 클래스를 말한다.
  • 중첩 클래스를 사용하면 두 클래스의 멤버들을 서로 쉽게 접근할 수 있다는 장점과
    외부에는 불필요한 관계 클래스를 감춤으로써 코드의 복잡성을 줄일 수 있다.

중첩클래스

class ClassName{
    class NestedclassNamed{

    }
}

중첩인터페이스

class ClassName{
    interface NestedInterfaceName{

    }
}
  • 인터페이스를 클래스 내부에 선언하는 이유는 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해

9.2 중첩 클래스

  • 클래스의 멤버로서 선언되는 중첩 클래스를 멤버 클래스라고 하며, 메소드 내부에서 선언되는 중첩 클래스를 로컬 클래스라고 한다.
  • 멤버 클래스는 클래스나 객체가 사용 중이라면 언제든지 재사용이 가능하지만, 로컬 클래스는 메소드 실행 시에만 사용되고,
    메소드가 실행 종료되면 없어진다.

멤버 클래스

  • 인스턴스 클래스:
    A 객체를 생성해야만 사용할 수 있는 B중첩 클래스
class A{
    class B{...}
}
  • 정적 멤버 클래스:
    A클래스로 바로 접근할 수 있는 B중첩 클래스
class A{
    static class B{...}
}

로컬 클래스

method()가 실행할 때만 사용할 수 있는 B 중첩 클래스

class A{

    void method(){
        class B{...}
    }
}

9.2.1 인스턴스 멤버 클래스

인스턴스 멤버 클래스는 static 키워드 없이 선언된 클래스를 말한다.

class A{
    class B{
            B(){}
            int field1;
            //static int field2; (x)
            void method(){}
            //static void method2(){} (x)
    }
}
  • A 클래스 외부에서 인스턴스 멤버 클래스 B의 객체를 생성하려면 먼저 A객체를 생성하고 B객체를 생성해야한다.
A a = new A();
A.B b = a.new B();
b.field1 = 3;
b.method1();

9.2.2 정적 멤버 클래스

class A{
    static class C{
            C(){}
            int field1;
            static int field2;
            void method(){}
            static void method2(){}
    }
}
  • A 클래스 외부에서 정적 멤버 클래스 C의 객체를 생성하기 위해서는 A 객체를 생성할 필요가 없고, C 객체를 생성하면 된다.
A.C c = new A.C();
c.field1 = 3;
c.method1();
A.C.field2 = 3;
A.C.method2();

9.2.3 로컬 클래스

  • 메소드 내에서 선언한 중첩 클래스
  • 로컬 클래스는 메소드 내부에서만 사용되므로 접근을 제한할 필요가 없기 때문에 로컬 클래스는 접근 제한자(public,private) 및 static을 붙일 수 없다.
  • 비동기 처리를 위해 스레드 객체를 만들 때 사용한다.
void method(){
    class D{
        D(){}
        int field;
        //static int field2;
        void method1(){}
        //static void method2(){}

    }

    D d= new D();
    d.field1 = 3;
    d.method1();
}

9.3 중첩 클래스의 접근 제한

9.3.1 바깥 필드와 메소드에서 사용제한

public Class A{
    B field1 = new B(); (o)
    C field2 = new C(); (o)

    void method1(){
        B var1 = new B();
        C var2 = new C();
    }

  static B field3 = new B(); (x)
    static C field4 = new C(); (o)

  static void method2(){
        B var1 = new B(); (x)
        C var2 = new C(); (o);
    }

    class B{}

    static class C{}
}

9.3.2 멤버 클래스에서 사용 제한

public class A{
    int field1;
    void method1(){}

    static int field2;
    static void method2(){}

    class B{
        void method(){
            field1 = 10; (o)
            method1();   (o)
            field2 = 10; (o)
            method2();   (o)
        }
    }

    static class C{
        void method(){
            field1 = 10; (x)
            method1();   (x)

            field2 = 10;
            method2();
        }    

    }
}

9.3.3 로컬 클래스에서 사용제한

  • 로컬 클래스 내부에서는 바깥 클래스의 필드나 메소드를 제한 없이 사용할 수 있다.
  • 로컬 클래스의 객체는 메소드 실행이 끝나도 힙 메모리에 존재해서 계속 사용 될 수 있다.
  • 매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 로컬 객체에서 사용할 경우 문제가 발생한다.
  • 자바는 이 문제를 해결하기 위해 컴파일 시 로컬 클래스에서 사용하는 매개 변수나 로컬 변수의 값을 로컬 클래스 내부에 복사해 두고 사용한다.

자바 7

  • 매개 변수나 로컬 변수가 수정되어 값이 변경되면 로컬 클래스에 복사 해둔 값과 달라지는 문제를 해결하기 위해 매개 변수나 로컬변수를 final로 막는다

  • 로컬 클래스에서 사용 가능한 것은 final로 선언된 매개 변수와 로컬 변수뿐이라는 것이다.(final 선언 안하면 컴파일 오류발생)

자바 8

  • final 키워드없이 선언된 배개 변수와 로컬 변수를 사용해도 컴파일 에러가 나지 않는다.
  • final 선언을 하지 않아도 여전히 값을 수정할 수 없는 final 특성을 갖는다.
  • final 키워드 존재 여부의 차이점은 로컬 클래스의 복사위치
    있으면? 로컬 클래스의 메소드 내부에 지역 변수로 복사
    없으면? 로컬 클래스의 필드로 복사된다.

요약 : 로컬 클래스의 내부 복사 위치에 신경 쓸 필요 없이 로컬 클래스에서 사용된 매개 변수와 로컬 변수는 모두 final특성을 갖는다.

public class Outter{

    //자바 7버전 이전
    public void method1(final int arg){
        final int localVariable = 1;
        arg = 100;(x)
        localVariable = 100;(x)

        class Inner{
            public void method(){
                int result = arg + localVariable;
            }
        }
    }
    //자바 8 이후
    public void method2(int arg){
        int localVariable = 1;
        arg = 100; (x)
        localVariable = 100;(x)

        class Inner{
            public void method(){
                int result = arg + localVariable;
            }
        }
    }

}

9.3.4 중첩 클래스에서 바깥 클래스 참조 얻기

  • 중첩 클래스에서 this 키워드를 사용하면 바깥 클래스의 객체 참조가 아니라, 중첩 클래스의 객체 참조가 된다.
  • 중첩 클래스 내부에서 바깥 클래스의 객체 참조를 얻으려면 바깥 클래스의 이름을 this 앞에 붙여주면 된다.
바깥클래스.this.필드
바깥클래스.this.메소드();
public class Outter{
    String field = "Outter-field";

    void method(){

    }

    class Nested{
        String field = "Nested-field"
        void method(){

        }

        void print(){
            this.method();  // 중첩 객체 참조
            Outter.this.method() // 바깥 객체 참조
        }
    }
}

9.4 중첩 인터페이스

  • 클래스의 멤버로 선언된 인터페이스를 말한다.
class A{
    interface I{
        void method();
    }
}
  • Setter 메소드로 구현 객체를 받아 필드에 대입한다.
public class Button{

    OnClickListener listener;

    void setOnClickListener(OnClickListener listener){
        this.listener = listener;
    }

    void touch(){
        listener.onClick();
    }

    interface OnclickListener{
        void onClick();
    }

}
Button btn = new Button();
btn.setOnclickListener(new CallListener()) --- OnclickListener를 구현한 클래스
btn.setOnclickListener(new MessageListener()) --- OnclickListener를 구현한 클래스

9.5 익명 객체

  • 이름이 없는 객체로, 단독으로 생성할 수 없고 클래스를 상속하거나 인터페이스를 구현해야만 생성할 수 있다.
  • 필드의 초기값이나 로컬 변수의 초기값, 매개 변수의 매개값으로 주로 대입된다.
class A{
    Parent field = new Parent(){
        int childField;
        void childMethod(){}
        // Parent의 메소드를 오버라이딩
        @Override
        void parentMethod(){}
    };
}
public class A {

    void method(){
        Parent localVar = new Parent(){
            int childField;
            void childMethod(){}
            @Override
            void parentMethod(){}
        };

    }
}
  • 메소드의 매개 변수가 부모타입일 경우 메소드 호출 코드에서 익명 자식 객체를 생성해서 매개값으로 대입할 수도 있다.
class A{
    void method1(Parent parent){}
    void method2();
}
method1(new Parent(){
        int childField;
        void childMethod(){}
        @Override
        void parentMethod(){}
})
  • 익명 자식 객체에 새롭게 정의된 필드와 메소드는 익명 자식 객체에서만 사용되고, 외부에서는 필드와 메소드에 접근할 수 없다.
  • 익명 자식 객체는 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용 할 수 있기 때문이다.
  • childField와 메소드 childMethod는 parentmethod()메소드 내에서 사용이 가능하나, A클래스의 필드인 field로는 접근할 수 없다.
class A{
    Parent field = new Parent(){
        int childField;
        void childMethod(){}
        @Override
        void parentMethod(){
            childField = 3;
            childMethod();
        }
    }
}

void method(){
    field.childField =3; (x)
    field.childMethod(); (x)
    field.parentMethod(); (o)
}

9.5.2 익명 구현 객체 생성

  • 인터페이스 타입으로 필드나 변수를 선언하고, 구현 객체를 초기값으로 대입하는 경우
class A{
    RemoteControl field = new RemoteControl(){
        @Override
        void turnOn(){}
    }
}
void method(){
    RemoteControl localVar = new RemoteControl(){
        @Override
        void turnOn(){}
    }
}
class A{
    void method1(RemoteControl rc){}

    void method2(){
        method1(new RemoteControl(){
            @Override
            void turnOn(){}
        })
    }
}

9.5.3 익명 객체의 로컬 변수 사용

[9.3.3]내용과 동일하며 클래스 이름의 존재 여부만 다를뿐 동작 방식을 동일하다.

void outMethod(final int arg1, int arg2){
    final int var1 = 1;
    int var2 = 2;

    인터페이스 변수 = new 인터페이스(){
        void method(){
            int result = arg1 + arg2 + var1 + var2
        }
    }
}
인터페이스 변수 = new 인터페이스(){

    int arg2 = 매개값; //final 아닌값
    int var2 = 2;

    void method(){
        int arg1 = 매개값; //final인값
        int var1 = 1;
        int result = arg1 + arg2 + var1 + var2;
    }
}

'책 > 이것이 자바다' 카테고리의 다른 글

[11장]기본 API클래스  (0) 2022.02.14
[10장]예외처리  (0) 2022.02.14
[8장]인터페이스  (0) 2022.02.14
[7장] 상속  (0) 2022.02.14
[6장] 객체  (0) 2022.02.14
    '책/이것이 자바다' 카테고리의 다른 글
    • [11장]기본 API클래스
    • [10장]예외처리
    • [8장]인터페이스
    • [7장] 상속
    노트코드
    노트코드
    노션 블로그에서 티스토리로 이전공사중

    티스토리툴바