
내부 클래스
클래스 안에 선언된 클래스
총 네 가지 경우로 나눌 수 있다.
예제와 함께 알아보자.
public class InnerExam1 {
// 필드를 선언 할 자리에 내부 클래스를 선언한 경우
class Add{
public int addInt(int number1, int number2){
int total = 0;
total = number1 + number2;
return total;
}
}
public static void main(String[] args) {
// InnerExam1 에 있는 test 라는 새 객체를 만들게
InnerExam1 test = new InnerExam1();
// InnerExam1 에 있는 Add 라는 클래스의 add 객체를 test 에다 만들게
InnerExam1.Add add = test.new Add();
int value=add.addInt(2, 5);
System.out.println(value);
}
}
필드를 선언 할 저리에 내부 클래스를 선언한 경우이다.
알다싶이 클래스는 인스턴스화를 하지 않으면 사용하지 못한다.
따라서 main 에서 인스턴스화를 거쳐주어야 한다.
// InnerExam1 에 있는 test 라는 새 객체를 만들게
InnerExam1 test = new InnerExam();
// InnerExam1 에 있는 Add 라는 클래스의 add 객체를 test 에다 만들게
InnerExam1.Add add = test.Add();
위 코드가 내부 클래스에서 가장 중요한 부분이다.
겉에 클래스를 먼서 인스턴스화 해준다음,
겉에 클래스 안에있는 내부 클래스를 가져와 만들어진 객체에 내부 클래스의 객체를 선언한다.
그 다음 쓰는 방법은 평소처럼 똑같다.
public class InnerExam2 {
// 필드를 선언 할 자리에 정적 내부 클래스를 선언한 경우
static class Plus{
int value = 0;
public void plus(){
value++;
}
}
public static void main(String[] args) {
InnerExam2.Plus test = new InnerExam2.Plus();
test.plus();
System.out.println(test.value);
}
}
위의 내부 클래스와 같이 필드를 선언 할 자리에 클래스가 있는 점은 같다. 하지만 이 경우에는 정적 클래스이다.
static 과 일반 클래스의 다른점이라 하면 정적 클래스는 인스턴스화를 거치지 않아도 된다는 점이다.
이 점을 고려해서 코드를 인스턴스화 시켜보자.
InnerExam2.Plus test = new InnerExam2.Plus();
public class InnerExam3 {
//method 안에서 클래스를 선언 한 경우
public void inner(){
class Plus{
int value;
public void increase(){
value++;
}
}
Plus plus = new Plus();
for(int i=0;i<5;i++){
plus.increase();
}
System.out.println(plus.value);
}
public static void main(String[] args) {
InnerExam3 exam3 = new InnerExam3();
exam3.inner();
}
}
위 코드는 필드를 선언 할 자리에 메서드를 선언하고
메서드 안에 클래스가 존재하는 경우이다.
이런 경우에는 class Plus 에 속한 모든 변수들은 inner method 안에서 밖에 사용할 수 없다.
즉, 지역 클래스인 것이다.
지역 클래스이기 때문에 main 에서 따로 인스턴스화 해줄 필요가 없다.
평소대로 클래스를 인스턴스화 해주고 함수를 호출해주면 된다.
// 추상 클래스
public abstract class Action {
public abstract void run();
}
// 추상 클래스 바로 이용하기
public class InnerExam4 {
public static void main(String[] args) {
Action action=new Action() {
@Override
public void run() {
System.out.println("RUN!!!!!!!!");
}
};
action.run();
}
}
위 코드의 경우에는 추상클래스 Action 에 대한 자식 클래스를 만들지 않았다.
이 처럼 추상클래스를 한 번만 쓰고 더 이상 필요 없는 경우에는 굳이 만들지 않고 위처럼 익명 중첩클래스를 사용한다.
기존에는 추상클래스에 대한 자식클래스를 만들어서 자식 클래스를 인스턴스화 했다.
추상클래스는 구체적이지 못하기 때문에 객체를 생성할 수가 없기 때문에 자식클래스를 만든것이다.
하지만 우리는 추상 클래스를 여러번 쓸 것이 아닌
한 번만 필요하기 때문에 굳이 자식클래스를 만들고 싶지 않다.
이럴때 쓰는 방법은 바로 추상클래스를 인스턴스화 하는 것이다.
Action action = new Action(){};
이렇게 평소처럼 인스턴스화를 한 후에 뒤에 { }; 를 붙여주면 된다.
{ }
해당 클래스를 상속받은 클래스의 이름 없는 객체를 생성하겠다
이렇게 되면 자식클래스 없이 추상클래스만으로 실행시킬 수 있다.