[17일차]내부 클래스

유태형·2022년 5월 18일
0

코드스테이츠

목록 보기
17/77

오늘의 목표

  1. 내부 클래스
  2. 인스턴스 내부 클래스
  3. 정적 내부 클래스
  4. 지역 내부 클래스
  5. 익명 내부 클래스



내부 클래스

내부 클래스(Inner Class)는 클래스 내에 선언된 클래스 입니다. 주로 외부 클래스와 연관되어 있을 때 사용되며, 내부 클래스는 외부클래스의 멤버들을 쉽게 접근 할 수 있습니다.

class 외부클래스{

class 인스턴스내부클래스{

}
static class 정적내부클래스{

}
void 메서드(){
	class 지역내부클래스{

	}
}

}

내부 클래스는 선언하는 위치나 예약어에 따라 크게 4가지 유형으로 나뉠 수 있습니다.

  • 인스턴스 내부 클래스(instance inner class) : 외부 클래스의 멤버변수 선언위치에 선언 : 외부 인스턴스 변수, 외부 전역 변수 사용 가능
  • 정적 내부 클래스(static inner class) : 외부 클래스의 멤버변수 선언위치에 선언 : 외부 전역 변수 사용 가능
  • 지역 내부 크래스(local inner class) : 외부 클래스의 메서드나 초기화블럭 안에 선언 : 외부 인스턴스 변수, 외부 전역 변수 사용 가능
  • 익명 내부 클래스(annonymouse inner class) : 클래스 선언과 객체 생성을 동시에 하는 일회용 익명 클래스 : 외부 인스턴스 변수, 외부 전역 변수 사용 가능



인스턴스 내부 클래스

package JAVA_Collection;

class Outer{
    private int num = 1; //인스턴스 변수
    private static int sNum; //클래스 변수

    private InClass inClass; //내부 클래스 변수

    public Outer(){ //생성자
        inClass = new InClass();
    }

    private class InClass{ //내부 클래스 선언
        int inNum =10;
		
        //private로 선언된 필드들에 쉽게 접근할 수 있습니다.
        void Test(){
            System.out.println("Outer num = " + num + "(외부 클래스의 인스턴스 변수)");
            System.out.println("Outer sNum = " + sNum + "(외부 클래스의 정적 변수)");
        }
    }

    public void testClass(){
        inClass.Test(); //내부 클래스의 메서드 호출
    }
}

public class InstanceInnerClass {
    public static void main(String[] args) {
        Outer outer = new Outer(); //외부 클래스의 인스턴스 생성
        System.out.println("외부 클래스 사용하여 내부 클래스 기능 호출");
        outer.testClass(); //외부 클래스의 메서드 -> 내부 클래스의 메서드
    }
}
//Console
외부 클래스 사용하여 내부 클래스 기능 호출
Outer num = 1(외부 클래스의 인스턴스 변수)
Outer sNum = 0(외부 클래스의 정적 변수)

외부 클래스의 private로 선언된 멤버변수를 내부 클래스에서 사용 가능합니다, 단 인스턴스 내부 클래스는 외부 클래스의 인스턴스를 생성한 이후에 사용가능합니다. 인스턴스 내부 클래스 내에 정적 변수와 정적 메서드를 선언할 수 없습니다.




정적 내부 클래스

인스턴스 내부 클래스와 선언할 위치는 동일하지만 클래스 멤버와 마찬가지로 static예약어를 사용하여 정적 내부 클래스임을 알립니다.

package JAVA_Collection;

class Outer2{
    private int num = 3; //인스턴스 변수
    private static int sNum = 4; //클래스 변수

    void getPrint(){ //외부 클래스의 인스턴스 메서드
        System.out.println("인스턴스 메서드");
    }
    static void getPrintStatic(){ //외부 클래스의 클래스 메서드
        System.out.println("스태틱 메서드");
    }
    static class StaticInClass{
        void test(){ //내부 클래스의 인스턴스 메서드 내부 클래스의 인스턴스화 필요
            System.out.println("Outer num = " +sNum + "(외부 클래스의 정적 변수)");
            getPrintStatic();
        }
        static void testStatic(){ //내부 클래스의 클래스 메서드, 내부 클래스의 인스턴스화 불필요
            System.out.println("스태틱 클래스의 스태틱 메서드");
        }
    }
}

public class StaticInnerClass {
    public static void main(String[] args) {
        Outer2.StaticInClass a = new Outer2.StaticInClass(); //내부 클래스 생성
        //스태틱 내부 클래스는 외부 인스턴스 없이 내부 인스턴스 생성 가능
        a.test(); //내부 클래스의 인스턴스 메서드
        Outer2.StaticInClass.testStatic(); //내부 클래스의 클래스 메서드
    }
}
//Console
Outer num = 4(외부 클래스의 정적 변수)
스태틱 메서드
스태틱 클래스의 스태틱 메서드



지역 내부 클래스

지역 내부 클래스는 클래스의 멤버가 아니라 메서드 내에서 정의 되는 메서드입니다. 지역 변수 처럼 정의된 메서드 내부에서만 사용가능 하므로 선언 후 바로 객체를 생성해서 사용합니다. 또 정적 클래스로 지정할 수 없습니다.

package JAVA_Collection;

class Outer3{
    int num = 3; //외부 클래스의 인스턴스 변수
    void test() {
        int num2 = 6; //지역 변수
        class LocalInClass{ //지역 내부 클래스
            void getPrint(){ //지역 내부 클래스의 인스턴스 메서드
                System.out.println(num); //지역 변수
                System.out.println(num2); //인스턴스 변수
            }
        }
        LocalInClass localInClass = new LocalInClass(); //지역 객체
        localInClass.getPrint(); //지역 내부 클래스의 인스턴스 메서드
    }
}

public class LocalInnerClass {
    public static void main(String[] args) {
        Outer3 outer = new Outer3(); //외부 객체 생성
        outer.test(); //외부 객체의 메서드 실행
    }
}
//Console
3 //지역 변수
6 //인스턴스 변수



익명 내부 클래스

익명 내부 클래스는 이름을 알 수 없는 내부 클래스를 의미합니다. 클래스 선언과 객체의 생성을 동시에 하기 때문에 하나의 객체만을 생성할 수 있으며 일회용 입니다. 지역내부 클래스와 유사하지만 일회성이고 더 간결하게 작성할 수 있습니다.

package JAVA_Collection;

interface Name{
    public static final String name = "코딩 자투리"; //상수
    public abstract void getName(); //추상 메서드
}

class TestClass2 implements Name{ //인터페이스를 구현한 클래스
    public void getName(){ //오버라이딩
        System.out.println("내 이름은 " + name);
    }
}

public class AnnonymousClass {
    public static void main(String[] args) {
        TestClass2 outer = new TestClass2(); //객체 생성
        outer.getName(); //객체의 메서드 호출

        new Name(){ //익명 클래스
            public void getName(){ //오버라이딩
                System.out.println("내 이름은 " + name);
            }
        }.getName(); //객체를 만들고 바로 실행
    }
}
//Console
내 이름은 코딩 자투리 //객체의 메서드 호출
내 이름은 코딩 자투리 //익명 클래스의 메서드 호출



후기

안드로이드를 공부하고 프로젝트를 진행할때 내부 클래스와 익명 클래스를 종종 자주 사용 하였었습니다. 스프링이라는 프레임 워크도 내부 클래스와 익명 클래스를 자주 사용한다는 소식을 들은 적이 있습니다. 오늘 학습을 잘 새겨두어 스프링 학습시 원할하도록 해야 겠습니다.




GitHub

https://github.com/ds02168/CodeStates/tree/main/src/JAVA_Collection

profile
오늘도 내일도 화이팅!

0개의 댓글