/* 덥고 지치고 짜증난다고... 안할꺼냐? 산소 아깝다 디져라 ㅋㅋ */
내부 클래스 많이 다뤄지지 않는 것 같아 그냥 지나치려 했으나 왠지 찝찝하다.
내부 클래스를 사용하는 주된 이유는 무엇일까?
만일, 어떤 클래스를 단 한 곳에서만 필요로 한다면, 이를 별도의 독립된 클래스로 정의할 필요없이
내부에 클래스를 바로 정의하여 사용하는 것이 편리하기 때문이다.
지금까지 사용했던 클래스들은 보통 다른 클래스를 사용하기 위해서 해당 클래스의 레퍼런스변수를 선언하고,
그 레퍼런스변수에 인스턴스화한 객체를 대입하여 사용했다. 그러나 이런 클래스간에는 다른 클래스가 해당 클래스의
내부 멤버변수나 메소드에 자주 접근하는 경우에는 접근 제어자에 의해 접근이 제약되므로 메소드를 통한 접근이나
다른 방법으로 접근해야만 한다.
만일, 모든 접근을 편하게 사용하기 위해 모두 public 접근제어자로 선언한다면 많은 문제가 생길 수도있다.
이러한 경우에 내부 클래스를 사용하게 되면 멤버변수나 메소드가 내부 클래스에는 public으로,
다른 클래스에는 private으로 사용 할 수 있다.
내부 클래스는 외부 클래스의 한 멤버처럼 사용된다.
따라서 private, static 등의 제어자를 내부 클래스에도 지정할 수 있다.
내부 클래스의 가장 큰 장점은 클래스에 의한 멤버이므로 내부 클래스에서 외부 클래스에 선언되어 있는
멤버 변수나 메소드들을 바로 액세스 할수 있다는 것이다.
@. 내부 클래스는 단독적으로 클래스가 형성화되어 있는 것이 아니기 때문에 항상 외부 클래스의 객체를
생성한 다음에 내부 클래스의 객체를 생성해야 한다.
@. 내부 클래스는 외부 클래스의 멤버 변수나 메소드를 public과 같이 접근 가능하다.
@. 내부 클래스에서 외부 클래스 자체의 객체를 명시적으로 참조할 필요가 있는 경우에는 외부 클래스명과 this를 사용한다.
@. 내부 클래스는 외부에서 단독으로 사용할 수 없다.
@. 내부 클래스를 static으로 선언하면 외부 클래스의 객체를 만들지 않고도 내부 클래스를 바로 사용할수있다.
단, static으로 선언된 내부클래스에는 static변수(클래스변수)만 사용가능하다.
@. 내부 클래스를 어떤 메소드 내부에서도 정의 할 수 있다.
@. 내부 클래스는 컴파일한 후에 외부클래스명$내부클래스명.class 형태로 생성된다.
class OuterTest2 // outer class
{
private int xVar;
public void outerMethod(int x)
{
xVar=x;
System.out.println("외부 클래스 xVar="+xVar);
}
class InnerTest2 // inner class
{
private int yVar;
public void innerMethod(int x, int y)
{
xVar=x;
yVar=y;
System.out.println("내부 클래스 xVar="+xVar);
System.out.println("내부 클래스 yVar="+yVar);
}
}
}
public class Test0707_2
{
public static void main(String[] args)
{
OuterTest2 ob1 = new OuterTest2(); // outer class instance
OuterTest2.InnerTest2 ob2 = ob1.new InnerTest2(); // inner class instance#1
OuterTest2.InnerTest2 ob3 = ( new OuterTest2() ).new InnerTest2(); // inner class instance#2
System.out.println("--- 외부 클래스 인스턴스 ---");
ob1.outerMethod(2);
System.out.println("--- 내부 클래스 인스턴스1 ---");
ob2.innerMethod(3,4);
System.out.println("--- 내부 클래스 인스턴스2 ---");
ob3.innerMethod(6,7);
}
}
class OuterClass // outer class
{
private int xVar;
private int yVar;
public OuterClass(int x,int y) // 생성자
{
xVar=x;
yVar=y;
InnerA A=new InnerA(); // 외부클래스 생성자에서 내부클래스 인스턴스를 생성하여 접근하고있다.
InnerB B=new InnerB(); // 마찬가지로 외부클래스 내에서 내부클래스 인스턴스 생성하여 접근하는 방식이 가능하다.
System.out.println("내부 클래스 InnerA : "+A.addMethod());
System.out.println("내부 클래스 InnerB : "+B.minuMethod());
}
class InnerA // inner class #1
{
int sum;
public InnerA() // 생성자
{
System.out.println("InnerA class constructor");
}
public int addMethod()
{
sum=xVar+yVar;
return sum;
}
}
class InnerB // inner class #2
{
int minu;
public InnerB() // 생성자
{
System.out.println("InnerB class constructor");
}
public int minuMethod()
{
minu=xVar-yVar;
return minu;
}
}
}
public class Test0707_3
{
public static void main(String[] args)
{
OuterClass ob=new OuterClass(10,20);
}
}
/* 아래 예제는 좀 거시기 하다 ㅋㅋ */
class SungYong // outer class
{
private String myname;
public SungYong(String myname) // constructor
{
this.myname=myname;
}
public void getMyname()
{
System.out.println("SungYong class "+myname);
}
class Emma // inner class
{
private String mylove;
public Emma(String mylove) // constructor
{
this.mylove=mylove;
}
public void getMylove()
{
System.out.println(myname+"\'s love is "+mylove);
}
class Harry // inner and inner class
{
private String enemy;
public Harry(String enemy) // constructor
{
this.enemy=enemy;
}
public void getMyEnemy()
{
System.out.println(myname+"\'s lover "+mylove+" hate "+enemy);
}
}
}
}
public class Test0707_4
{
public static void main(String[] args)
{
SungYong ob1=new SungYong("이성용"); // 외부클래스 인스턴스 생성
SungYong.Emma ob2=ob1.new Emma("Emma"); // 내부클래스 인스턴스 생성
SungYong.Emma.Harry ob3=ob2.new Harry("Harry"); // 내부클래스의 내부클래스 인스턴스 생성
ob1.getMyname();
ob2.getMylove();
ob3.getMyEnemy();
}
}
[출처] 내부 클래스 (inner class)|작성자 이성용