본문 바로가기

자바(JAVA)
[자바(Java)] 중첩 클래스, 익명 클래스

//중첩 클래스(inner class) : A$B.class   
    ~ 사용하는 이유: 두 클래스의 멤버들을 서로 쉽게 접근할 수 있다.

class

class ClassName { //외곽 클래스(outer class)
	class NestedClassName { //중첩 클래스(inner class)
	}
}

//클래스가 선언되는 위치에 따라

- 내부 클래스의 객체를 생성하려면, 먼저 외부 클래스의 객체를 먼저 생성한 다음 내부 클래스의 객체 생성

1. 멤버 클래스

- 인스턴스 멤버 클래스
   ~ static 키워드 없이 선언된 클래스.  
   ~ 인스턴스 필드와 메서드만 선언 가능.

**A 객체를 생성해야 사용할 수 있는 B 클래스 ↓

class A {
	class B { ... }
}

 

- 정적 멤버 클래스(static)
   ~ 모든 종류의 필드와 메서드 선언 가능

** A 클래스로 바로 접근할 수 있는 B 클래스

class A{
	class B { ..... } 
  		static in field
        void method1(){}
        
}

 

2. 로컬 클래스
- 인스턴스 필드와 메서드만 선언 가능

** method()가 실행될 때만 사용할 수 있는 B 클래스

class A{
	void method() {
    	class B { ..... }
    }
}

package ex01.sample1020;

class A {
	A() {
		System.out.println("A 객체 생성");
	}
	
	// 인스턴스 멤버 클래스
	class B {
		B() {
			System.out.println("B 객체 생성");
		}
			int field1;
			// static int field2; (X)
			void method1() {}
			// static void method2() { } (X)
	}
	
	// 정적 멤버 클래스
	static class C{
		C() {
			System.out.println("C 객체 생성");
		}
		int field1;
		static int field2;
		void method1() {}
		static void method2() {}
	}
	
	void method() {
		// local class
		class D {
			D() {
				System.out.println("D 객체 생성");
			}
			int field1;
			void method1() { }
		}
		D d = new D();
		d.field1 = 5;
		d.method1();
	}
}

 

package ex01.sample1020;

public class MainTest {

	public static void main(String[] args) {
		A a = new A();
	
		A.B b = a.new B();
		b.field1 = 3;
		b.method1();
		
		A.C c = new A.C();
		c.field1 = 3;
		c.method1();
		
		a.method();
	}
}

package ex01.sapmle1020_1;

class A {
	// 인스턴스 필드
	B field1 = new B();
	C field2 = new C();
	
	// 인스턴스 메서드
	void method1() {
		B var1 = new B();
		C var2 = new C();
	}
	
	// 정적 메서드
	static void method2() {
		// B var1 = new B();
		C var2 = new C();
	}
	
	class B { } //인스턴스 멤버 클래스
	
	static class C{ } //정적 멤버 클래스
}

package ex01.sapmle1020_1;

public class Parcel1 {
	
	class Contents {
		private int i = 11;
		public int value()  {
			return i;
		}
	}
		class Destination {
			private String label;
			Destination(String whereTo) {
				label = whereTo;
			}
			String readLabel() {
				return label;
			}
		}
			
			public void ship(String dest) {
				Contents c = new Contents();
				Destination d = new Destination(dest);
				System.out.println(d.readLabel());
			}

	public static void main(String[] args) {
		Parcel1 p = new Parcel1();
		p.ship("내부 클래스 생성");
	}
	
}

 

package ex01.sapmle1020_1;

public class Parcel2 {
	
	class Contents { 
		private int i = 11;
		public int value()  {
			return i;
		}
	}
	
		class Destination {
			private String label;
			Destination(String whereTo) {
				label = whereTo;
			}
			String readLabel() {
				return label;
			}
		}
		
		public Destination to(String s) {
			return new Destination(s);	
		}
		
		public Contents contents() {
			return new Contents();
		}

		public void ship(String dest) {
			Contents c = new Contents();
			Destination d = new Destination(dest);
			System.out.println(d.readLabel());
		}

	public static void main(String[] args) {
		Parcel2 p = new Parcel2();
		p.ship("내부 클래스 생성");
		Parcel2 q = new Parcel2();

		Parcel2.Contents c = q.contents();
		Parcel2.Destination d = q.to("내부 클래스 정의");
	}
}

package ex01.sapmle1020_1;

interface Selector {
	boolean end();
	Object current();
	void next();
}

public class Sequence {
	private Object[] items;
	private int next = 0;
	public Sequence(int size) {
		items = new Object[size];
	}
	
	public void add(Object x) {
		if(next < items.length)
			items[next++] = x;
	}
	
	private class SequenceSelector implements Selector {
		private int i = 0;
		public boolean end() {
			return i == items.length;
		}
		public Object current() {
			return items[i];
		}
		public void next() {
			if(i < items.length)
				i++;
		}
	}
	
	public Selector selector() {
		return new SequenceSelector();
	}

	public static void main(String[] args) {
		Sequence sequence = new Sequence(10);
		for(int i = 0; i < 10; i++)
			sequence.add(Integer.toString(i));
		Selector selector = sequence.selector();
		while(!selector.end()) {
			System.out.println(selector.current() + "");
			selector.next();
		}
			
	}

}

//익명 클래스, Anonymous Class
- 이름이 없는 클래스
- 반드시 인터페이스가 필요하다.(자바 특성)
- 객체를 딱 1개만 만들 수 있다. > 재사용 불가
- 클래스 선언과 객체 생성 시점이 동일하다. > 객체 생성 시 인터페이스 구현
    ~ 익명 객체 생성


package com.test.obj.type;

public class Ex28_Anonymous {

	public static void main(String[] args) {

		//요구사항] 인터페이스를 구현한 클래스 선언하기 > 객체를 생성하기(목적)
		
		//추상 클래스. 인터페이스 > 추상 메서드 때문에 객체 생성 불가
//		AA o3 = new AA();
//		o3.aaa();
		
		AA o4 = new AA() {
			@Override
			public void aaa() {
				System.out.println("추상 메서드 구현");
			}
		};
		
		o4.aaa();
		
		AA o5 = new AA() {
			@Override
			public void aaa() {
				System.out.println("추상 메서드 구현2");
			}
		};
		
		o5.aaa();
		
	} //main
	
}

interface AA{
	void aaa();
}