[ITWILL : JAVA]내부클래스

ITWILL학원 : 20강 JAVA BY 윤미영강사

1. 내부클래스(p363)

  • 클래스가 서로 밀접한 관련이 있을때 객체생성없이 사용하기 용이하다
  • 주로 이미 만들어진 내부클래스라이브러리를 사용.
  • 공통점 : static 변수는 가질 수 없지만, final static 변수는 가질 수 있다.
    • 만약 상수가 아닌 변수형태로 선언이 되어있다면 그건 앞에 final이 생략되어진 것임.
    • 변수를 사용하고싶다면 차라리 외부클래스의 멤버변수로 선언하는 것이 낫다.
  • 내부클래스의 종류 4가지 :

https://github.com/burberry-check/java-basic/wiki/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4,-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

2. 인스턴스 내부클래스

  • 내부클래스를 외부클래스의 멤버변수 선언위치에 선언하는 것.

  • 인스턴스내부클래스는 외부클래스의 멤버변수를 자신의 멤버변수처럼 불러와서 쓸 수 있다.

  • 단독으로 사용하기도한다.

  • 내부클래스의 메서드 사용하는 방법 :

    1. 외부클래스 객체생성 : 외부클래스명 A = new 외부클래스명();
    2. 내부클래스 객체생성 : 내부클래스명 B = A.new 내부클래스명();
    3. 내부클래스의 메서드 사용 : B.method();
    • 이러한 것을 단독사용이라고 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class InstanceInner {
private int outerMember = 1;

private void outerMethod(){
Inner inner = new Inner();
inner.innnerMember = 11;
inner.innerMethod();
}

class Inner{
int innnerMember = 10;
//static int staticMember = 10; staitc멤버변수 선언 불가. 만약 상수가 아닌 변수형태로 선언이 되어있다면 그건 앞에 static이 생략되어진 것임.
static final int finalStaticMember = 20; //단 static final형태는 선언할 수 있다.

private void innerMethod(){
System.out.printf("out : %d, inner %d%n", outerMember, innnerMember);
}
}

//내부클래스 메서드 사용은 어떻게 할까?
public static void main(String[] args) {
InstanceInner ilt = new InstanceInner(); //1.외부클래스객체생성
Inner inner = ilt.new Inner(); //2.내부클래스객채생성
inner.innerMethod(); //3.내부클래스의 메서드사용

}
}

3. 지역클래스(local class)

  • 내부클래스가 외부클래스의 메서드안에서 정의되어지는 것.
  • 지역클래스는 단독으로 사용하지않고 내부에서 객체생성 후 호출해서 사용.
    • 단독사용의 의미 : 직접 메서드를 불러와서사용,
    • 지역클래스인 경우 메서드를 호출하는 순간 객채생성하고 바로 사용할 수 있게해야한다. 즉 단독사용처럼 직접 클래스이름을 불러 사용하는 것이 아니라 지역클래스가 속한 외부클래스메서드를 부르면서 그 속에 있는 클래스가 자동으로 사용되게끔 하는 것이다.
1
2
3
4
5
6
7
8
9
10
class OuterClass(){
...
public methodA(){ //멤버메서드
class InnerClass(){ //로컬클래스
...
}
}
}

//객체생성 후 호출해서 주로 사용

4. 익명클래스(p373)

  • 인터페이스를 구현할 목적으로 사용.
  • 실무에서 자주 사용.
  • 익명클래스의 override는 인터페이스 규칙에 의해 public을 붙여줘야한다
  • 익명클래스를 어떨때 사용할까?
    • 독립적인 클래스 사용 : 인터페이스를 구현한 클래스를 여러번 사용할때 용이.Intf a는 언제어디서나 불러서 사용가능
    • 익명클래스 사용 : 인터페이스를 구현한 클래스를 딱 한번 사용할때 용이. 익명클래스는 Intf b에서만 사용가능. 이름이 없기때문에 불러서 사용할 수 없다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
interface Intf{
void methodInf();
}

class A implements Intf{
@Override
public void methodInf() {
System.out.println("인터페이스 메서드 오버라이딩");
}
}

public class test {

public static void main(String[] args){

//기본적인 interface구현(독립적인 클래스사용)
Intf a = new A();
a.methodInf();

//익명클래스를 이용한 interface구현
Intf b = new Intf(){
@Override
public void methodInf() {
System.out.println("익명클래스로 인터페이스 메서드 오버라이딩");
}
};
b.methodInf();
}
}

5. 내부클래스 예시

다양한 내부클래스를 생성한 뒤 main메서드로 호출해보자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
interface InfoPrintable{
public void printInfo();
}

public class VariousInnerClassTest {

//멤버메서드(매개변수가 인터페이스)
public void useInnerClass(InfoPrintable inner){
inner.printInfo();
}

//멤버메서드
public void useSpeakerTest(){

//로컬 내부클래스생성(메서드안에 선언한 내부클래스=로컬클래스)
class EngSpeaker implements InfoPrintable{
@Override
public void printInfo() {
System.out.println("로컬 내부 클래스");
}
}//EngSpeaker닫음

//멤버메서드사용하여 클래스 부르기
//1. 익명의 내부클래스 생성
useInnerClass(new InfoPrintable(){
@Override
public void printInfo() {
System.out.println("익명의 내부클래스");
}
});

//2. 로컬내부클래스부르기
useInnerClass(new EngSpeaker());

//3. 인스턴스내부클래스부르기
useInnerClass(new InstanceInnerClass());

//4. 걍 밖에있는클래스
useInnerClass(new SomeClass());

}//useSpeakerTest메서드닫음

//인스턴스 내부클래스(외부클래스의 멤버에 생성)
class InstanceInnerClass implements InfoPrintable{
@Override
public void printInfo() {
System.out.println("인스턴스 내부클래스 사용");
}

}//InstanceInnerClass닫음


//만든 내부클래스를 main메서드로 호출해보자
public static void main(String[] args){

VariousInnerClassTest vt = new VariousInnerClassTest();
vt.useSpeakerTest();

}

}//VariousInnerClassTest닫음

//걍 다른 클래스인데 인터페이스구현
class SomeClass implements InfoPrintable{

@Override
public void printInfo() {
System.out.println("걍 상관없는 일반 클래스");
}

}