Binary World

JAVA CLASS : Inner Class(내부 클래스) 본문

개발자의 길/JAVA

JAVA CLASS : Inner Class(내부 클래스)

모쿠 2017. 1. 12. 10:32

<Inner Class (내부 클래스)>


* 내부 클래스(Inner Class): 다른 클래스 내부에서 정의된 클래스

1. 멤버 내부 클래스(member inner class):

   - 멤버 변수를 선언하는 위치에서 정의하는 내부 클래스

   - 외부 클래스의 인스턴스가 생성되어야만 객체 생성이 가능함

2. static 내부 클래스(static  inner class), 중첩 클래스(nested class)

   - 멤버 변수를 선언하는 위치에서 static으로 정의한 내부 클래스

   - 외부 클래스의 인스턴스를 생성하지 않아도 객체 생성이 가능함

   - 외부 클래스와 상관이 없는 클래스라고 생각해도 됨

3. 지역 내부 클래스(local inner class): 메소드 안에서 정의하는 클래스

    1) 이름이 있는 local 클래스

    2) 이름이 없는 local 클래스 : 익명 클래스(anonymous class)

       -> 람다 표현식(lambda expression)


* 내부 클래스의 변수 선언:

1. 멤버 변수 : 클래스에서 선언된 변수

   - 클래스 내부 어느 곳에서나 사용할 수 있는 변수

   - 수식어(public, private, static, ...)를 사용할 수 있음

2. 지역 변수 : 메소드 안에서 선언하는 변수

   - 지역 변수가 선언된 곳에서부터 변수가 속한 블록이 끝나는 곳까지 사용할 수 있는 변수

   - 접근 수식어(public, private, static, ...)를 사용할 수 없음

   - final은 사용 가능


<프로그램 코드>


1. 내부 클래스의 인스턴스 생성 및 변경 출력


* InnerMain01.java (외부 클래스 인스턴스 생성 및 출력)


public class InnerMain01 {

private int x; // 멤버 변수

public static void main(String[] args){

int y; // 지역 변수

// 외부 클래스 OuterClass의 인스턴스를 생성

OuterClass out1 = new OuterClass(100);

// 메소드의 호출은 참조 변수를 통해서

out1.display();

// 외부 클래스의 인스턴스를 생성했다고 해서

// 내부 클래스의 인스턴스까지 생성된 것은 아님!

// -> 외부 클래스 참조변수가 내부 클래스의 메소드를 사용할 수는 없음.

// 내부 클래스의 인스턴스 생성:

// (외부클래스 이름).(내부 클래스 이름 변수이름) (변수이름) = 

//  (외부 클래스의 참조 변수).new (내부 클래스 생성자)();

OuterClass.InnerClass inner1 = out1.new InnerClass(200);

inner1.printValues();

System.out.println();

// 내부 클래스 인스턴스를 통한 외부 클래스 멤버변수 변경

inner1.setOuterValue(123);

inner1.printValues();

out1.display();

System.out.println();

// out1 인스턴스를 통한 두번째 InnerClass 인스턴스 생성

OuterClass.InnerClass inner2 = out1.new InnerClass(300);

inner2.printValues();

System.out.println();

inner2.setOuterValue(111);

inner2.printValues();

inner1.printValues();

} // end main()


} // end class InnerMain01 



*OuterClass.java (내부 클래스를 포함한 외부 클래스)


package edu.java.inner01;


// 클래스: 멤버 변수(+ 생성자) + 메소드 => 데이터 타입


public class OuterClass {

private int value1; // 멤버 변수(어디서든 사용 가능)


public OuterClass(int v) {

this.value1 = v;

}


public void display() {

System.out.println("value1 = " + value1);

}


// 멤버 내부 클래스(member inner class)

class InnerClass {

private int value2;


public InnerClass(int v) {

this.value2 = v;

}


// 외부 클래스의 멤버 변수는 내부 클래스에서 직접 사용이 가능

public void setOuterValue(int value) {

value1 = value;

}


public void printValues() {

// 외부 클래스의 멤버 변수 출력

System.out.println("outer value: " + value1);

// 내부 클래스의 멤버 변수 출력

System.out.println("inner value: " + value2);

}

} // end class InnerClass


} // end class OuterClass 


* 출력화면


value1 = 100

outer value: 100

inner value: 200


outer value: 123

inner value: 200

value1 = 123


outer value: 123

inner value: 300


outer value: 111

inner value: 300

outer value: 111

inner value: 200 



2. 멤버 내부 클래스(member inner class)를 사용하는 경우

- 상속관계로는 묶을 수 없지만, A라는 객체가 생성된 이후에만 존재할 수 있는 B라는 객체가 있다면 B를 A의 내부 클래스로 정의함.

  (예) 자동차 - 타이어, PC - CPU/RAM


* Car.java


package edu.java.inner02;


public class Car {

private String name;

public Car(String name) {

this.name = name;

}

// 멤버 내부 클래스(member inner class)

public class Tire {

private int size;

public Tire(int size){

this.size = size;

}

public void display(){

System.out.println("--- 자동차 정보 ---");

System.out.println("자동차 이름: " + name);

System.out.println("타이어 크기: " + size);

}

} // end class Tire


} // end class Car 



* InnerMain02.java


package edu.java.inner02;


public class InnerMain02 {


public static void main(String[] args) {

// 자동차 객체가 먼저 만들어져야 타이어 객체를 만들 수 있음

Car car1 = new Car("포르쉐");

Car.Tire tire1 = car1.new Tire(20);

tire1.display();

System.out.println();

Car car2 = new Car("모닝");

Car.Tire tire2 = car2.new Tire(15);

tire2.display();

System.out.println();

Car.Tire tire3 = new Car("제네시스").new Tire(19);

tire3.display();

} // end main()


} // end class InnerMain02 



* 출력화면


--- 자동차 정보 ---

자동차 이름: 포르쉐

타이어 크기: 20


--- 자동차 정보 ---

자동차 이름: 모닝

타이어 크기: 15


--- 자동차 정보 ---

자동차 이름: 제네시스

타이어 크기: 19 


3. 지역 클래스 메소드 사용하기

지역 클래스 : 지역 변수를 선언하는 위치에서 정의하는 클래스


* 지역 클래스의 메소드들을 외부에서 사용하는 방법:

  1. 지역 클래스의 메소드들을 선언한 인터페이스를 정의

  2. 지역 클래스가 인터페이스를 구현하도록 정의

  3. 다형성을 사용해서 메소드의 리턴 타입으로 인터페이스를 사용할 수 있음.


* Person.java



package edu.java.inner06;


public class Person {

private String name; // 멤버 변수

// Person 클래스의 생성자

public Person(String name){

this.name = name;

}

// Person 클래스의 메소드

public PersonInterface setAge(int age){

// 지역 클래스(local class)를 정의

class PersonWithAge implements PersonInterface{


private int age; // 지역 클래스의 멤버 변수

public PersonWithAge(int age){

this.age = age;

}

public void showInfo(){

System.out.println("이름: " + name);

System.out.println("나이: " + age);

}

public void hello() {

System.out.println("안녕하세요.");

}

} // end class PersonWithAge

PersonWithAge instance = new PersonWithAge(age);

return instance;

} // end setAge()


} // end class Person


interface PersonInterface{

public abstract void showInfo();

public abstract void hello();

} // end interface PersonInterface 



* InnerMain06

package edu.java.inner06;


public class InnerMain06 {


public static void main(String[] args) {


Person p = new Person("진혁");

PersonInterface instance = p.setAge(20);

instance.showInfo();

instance.hello();

} // end main()


} // end class InnerMain06 


* 출력화면


이름: 진혁

나이: 20

안녕하세요. 




'개발자의 길 > JAVA' 카테고리의 다른 글

JAVA CLASS : 쓰레드(Thread)  (0) 2017.01.12
JAVA CLASS : 예외(Exception)  (0) 2017.01.12
JAVA CLASS : Inner Class (연습문제 4, 5)  (0) 2017.01.10
JAVA CLASS : Map-TreeMap 클래스  (0) 2017.01.09
JAVA CLASS : Map-HashMap 클래스  (0) 2017.01.09
Comments