■ 이너클래스 : 내부클래스 : 중첩클래스
1. 이너클래스의 이해와 특징
특정 클래스 내에 또 다른 클래스가 정의되는 것을 의미한다. 이런 이너 클래스가 필요한 이유는 지금까지 작업해왔던 클래스들과는 다르게 독립적이지는 않지만 하나의 멤버처럼 사용할 수 있는 특징이 있다.
2. 이너클래스를 정의할 때 주의사항이자 장점
이너클래스는 외부 클래스의 모든 멤버들을 마치 자신의 멤버처럼 사용할 수 있다.
static 이너 클래스는 제외하고는 다른 이너 클래스는 항상 외부 클래스를 통해야 생성이 가능하다.
외부클래스명$내부클래스명.class로 class 파일이 만들어짐.
3. 이너클래스의 종류
member class는 가장 기본적인 형태이다.
static, local class는 member class에서 파생된 것으로 볼 수 있다.
anonymous class가 가장 많이 쓰인다.
4. Member 이너클래스
말 그대로 객체를 생성해야만 사용할 수 있는 멤버들과 같은 위치에 정의되는 클래스를 말한다. 즉 이너클래스는 생성하려면 외부 클래스의 객체를 생성한 후에 생성할 수 있다.
inner class 내부에는 static이 존재할 수 없다.
Outer.Inner in = new Outer().new Inner(); 형태로 사용
package jun.java.exam04;
class OuterEx {
public class InnerEx{
int x = 5;
}
}
package jun.java.exam04;
public class InnerExOne {
public static void main(String[] args) {
// 외부클래스 먼저 생성하고
OuterEx eo = new OuterEx();
// 외부를 통해서 내부클래스를 생성한다.
OuterEx.InnerEx ei = eo.new InnerEx();
System.out.println("ei.x = " + ei.x);
}
}
OuterEx // OuterEx.class
InnerEx // OuterEx$InnerEx.class 로 파일이 만들어진다
<결과>
ei.x = 5
package jun.java.exam05;
public class MemberInner {
int a = 10;
private int b = 100;
static int c = 200;
class Inner { // 이너클래스 정의
public void printData() {
System.out.println("int a : " +a);
System.out.println("private int b : " +b); // 주시하자!
System.out.println("static int c : " +c);
}
}
public static void main(String[] args) {
// MemberInner outer = new MemberInner();
// MemberInner.Inner inner = new outer.Inner();
MemberInner.Inner inner = new MemberInner().new Inner();
inner.printData();
}
}
<결과>
int a : 10
private int b : 100
static int c : 200
private 변수도 사용가능
클래스의 멤버 메서드 안에서는 static 변수도 쓸 수 있다.
5. Local 이너클래스
Local 이너클래스는 특정 메소드 안에서 정의되는 클래스를 말한다. 다시 말해서 특정 메소드 안에서 선언되는 지연변수와 같은 것이다. 메소드가 호출될 때 생성할 수 있으며 메소드의 수행력이 끝나면 지역변수와 같이 자동소멸된다.
잘 사용되지 않는다.
method 내부에 class가 존재하며 method 실행할 때 실행된다.
package jun.java.exam04;
public class StaticExam {
private int x;
private static int y;
public static void main(String[] args) {
// System.out.println("x = " + x); // 이렇게 쓰면 에러 발생. 스태틱 메서드 안에서는 스태틱 변수만 써야 한다.
System.out.println("y = ");
// 옳은 방식
StaticExam se = new StaticExam();
System.out.println("x = " +se.x );
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public static int getY() { // getter, setter 에서 static 지워도 에러가 안 남. 왜? 4번의 딱 하나 예외
// 클래스의 멤버 메서드의 경우에는 예외
return y;
}
public static void setY(int y) {
StaticExam.y = y;
}
}
<결과>
int a : 100
int b : 200
final int c : 1000
int b = 200 은 class Inner와 등급이 같다.
그래서 지역변수를 가져올 수 없다. 하지만 그럼 정보교환이 자유롭지 않기 때문에 7.0부터 사용가능하게 바뀌었다.
6. static 이너클래스
static 이너클래스로 어쩔 수 없지 정의하는 경우가 있는데 그것은 바로 이너클래스 안에 static 변수를 가지고 있다면 어쩔 수 없지 해당 이너 클래스는 static으로 선언하여야 한다.
inner class의 지정어로 static을 기재한다. 따라서 class 내부에선 static 변수 사용 가능.
Outer.Inner in = new Outer.Inner(); [ 또는 new Outer().new Inner() ] 사용 가능.
만약 inner class가 main 안에 존재할 때는 Outer$Inner.class를 실행시킴.
static 변수나 메소드들은 객체를 생성하지 않고도 접근이 가능하다고 했었다. 즉 static 이너클래스는 외부클래스를 생성하지 않고도 [ 외부_클래스명.내부클래스_생성자() ]로 생성이 가능하다.
static 이너클래스도 특수한 형태일 뿐이다. static을 빼면 Member 이너클래스랑 차이가 없다.
package jun.java.exam07;
public class StaticInner {
int a = 10;
private int b = 100;
static int c = 200;
static class Inner {
// 어쩔 수 없이 이너클래스를 static으로 선언해야 할 경우가 있다.
// 그건 바로 이너클래스의 멤버들 중 static 멤버가 하나라도 있을 때이다.
static int d = 1000;
public void printData() {
// System.out.println("int a : " + a); // 오류
// System.out.println("private int b : " + b); // 오류
System.out.println("static int c : " + c);
}
}
public static void main(String[] args) {
// 또 다른 독립된 객체에서 static 이너클래스 생성시
StaticInner.Inner inner = new StaticInner.Inner();
inner.printData();
}
}
package jun.java.exam08;
public class OuterEx { // OuterEx.class
public static class InnerEx { // OuterEx$InnerEx.class
static int x = 10;
}
public static void main(String[] args) {
OuterEx.InnerEx ei = new OuterEx.InnerEx();
System.out.println("ei.x = " + ei.x);
System.out.println("ei.x = " + OuterEx.InnerEx.x);
}
} // 실행하려면 java OuterEx$InnerEx
7. Anonymous(익명) 이너클래스
익명이란? 이름이 없는 것을 의미한다. 이것을 자바의 프로그램적으로 해석하면 정의된 클래스의 이름이 없다는 것이 된다.
Event와 관련이 있다.
interface 구현이 필요없다.
일반 메소드 내부에서 정의부를 가질 수 있다.
abstract를 상속받을 수 있다.
반드시 final로 선언해야 한다.
implements를 할 때는 한 개만 implements한다.
package jun.java.exam09;
abstract class TestAbst {
int data = 10000;
public abstract void printData(); // 추상메소드
}
package jun.java.exam09;
public class AnonyInner {
TestAbst inn = new TestAbst() {
public void printData() { // 미완성된 것을 완성한다.
System.out.println("data : " + data);
}
};
public static void main(String[] args) {
AnonyInner ai = new AnonyInner();
ai.inn.printData();
}
}
■ 열거형
1. 열거형의 정의
C언어에서 정수를 자동적으로 증가하여 상수들로 만들어 쓰이는 열거체(enum)와 비슷하며 자바에서 얘기하는 열거형은 상수를 하나의 객체로 인식하고 여러개의 상수 객체들을 한곳에 모아둔 하나의 묶음(객체)이라 할 수 있다.
2. 열거형의 구성
package jun.java.exam01;
public class EnumEx1 { // EnumEx1.class
public enum Lesson { // EnnumEx1$Lesson.class - 이너 클래스와 같음
JAVA, XML, EJB
}
public static void main(String[] args) {
Lesson le = Lesson.JAVA;
System.out.println("Lesson : " + le);
System.out.println("XML : " + Lesson.XML);
}
}
<결과>
Lesson : JAVA
XML : XML
3. 열거형의 실체
열거형은 내부에서 순차적으로 정의되는 값들을 JAVA, MXL, EJB라는 이름으로 그냥 일반적인 상수라는 개념만으로 저장되는 것이 아니다. 정확히 얘기를 하자면 java.lang이라는 패키지에 Enum이라는 추상 클래스를 상속받는 이너클래스가 정의되는 것이다.
앞의 예제에서 Lesson이라는 enumerated types(열거형)를 가지고 예를 들어보면 다음과 같다
public static final class EnumEx1$Lesson extends Enum
package jun.java.exam02;
public class EnumEx2 {
public enum Item {
Add, Del, Search, Cancel
}
public static void main(String[] args) {
Item al = Item.Search;
if (al instanceof Object) { // 열거형이 객체인지 아닌지 비교
System.out.println(al.toString() + " ^^");
System.out.println("OK! instance Object");
System.out.println("저장된 실제 정수값 : " + al.ordinal());
}
Item[] items = Item.values();
System.out.println("items.length : " + items.length);
for(Item n : Item.values())
System.out.println(n + ":" + n.ordinal());
}
}
// ordinal은 숫자값
// values는 배열로
// C 언어에서는 메뉴만드는데
// JAVA에서는 보안등급 만들 때
// 열거형의 실체는 이너클래스다
<결과>
Search ^^
OK! instance Object
저장된 실제 정수값 : 2
items.length : 4
Add:0
Del:1
Search:2
Cancel:3
ordinal은 숫자값
values는 배열로
C 언어에서는 메뉴만드는 데, JAVA에서는 보안등급 만들 때 사용한다.
// 열거형의 실체는 이너클래스다
'IT&코딩 > Java' 카테고리의 다른 글
Java - 14일차 (패키지, 예외처리, 단언) (0) | 2022.11.01 |
---|---|
Java - 13일차 (알아두면 유용한 클래스) (2) | 2022.10.29 |
Java - 11일차 (추상클래스와 인터페이스) (0) | 2022.10.27 |
Java - 10일차 (상속과 다형성) (0) | 2022.10.26 |
Java - 9일차 (객체지향 프로그래밍(클래스)2) (0) | 2022.10.24 |