내부클래스 : 최상위 클래스에 포함된 클래스
선언되는 위치와 방법에 따라서 4가지 종류로 구분
class TopClass {
class Inner {}
// 클래스 영역
메서드 () {
// 메서드 영역
}
}
1. 내부클래스(InnerClass)
: 인클로징 클래스의 변수를 접근할 수 있음
: static이 붙지않은 클래스 영역에 선언된 클래스
: 인스턴스 변수
: 클래스에만 선언 가능하고 인터페이스에는 선언이 불가능함
: 외부에서 참조시 - 인클로징 클래스의 이름.이너 클래스 이름
: 인클로징 외부에서 이너 클래스의 객체 생성하기
Cart cart = new Cart();
Cart.Item item = cart.new Item();
2. 정적내부클래스(StaticInnerClass)
: static이 붙은 클래스 영역에 선언된 클래스
: 클래스 변수
: static 변수나 메서드를 선언할 수 있음
3. 지역내부클래스(LocalInnerClass)
: 메서드 안에 선언되는 내부 클래스
4. InnerAnnoymous(익명) : 클래스, 메서드 영역에 선언됨, 이름이 없음
: 두가지 동시 처리 (클래스 선언, 객체 생성)
* 메서드 안에 선언된 클래스가 메서드의 지역변수를 참조할 때는
final로 선언된 변수만 사용 가능함
5. 정적내부 인터페이스
- 내부 인터페이스는 정적 내부 인터페이스 한종류만 가능함
class Top { => 탑 클래스
class InnerMember { } => 내부 클래스 (멤버변수 자리에 선언)
static class StaticMember {} => 정적 내부 클래스
public void test () {
final int val = 100; => 지역 내부 클래스 (메서드 내에 선언, 이름이 있음)
class InnerLocalNamed {
public void print() {
System.out.println(val);
}
}
new Random[상위클래스, 인터페이스]() { } => 익명 클래스 (메서드 내에 선언, 이름이 없음), 이벤트방식으로 가장 많이 사용됨
}
}
소스
public class InnerTest {
public void call(Parent p) {
}
public void call(Runnable r) {
}
public void test() {
call(new Parent() {
public void call() {
System.out.println("재정의함");
}
});
// 익명 클래스를 변수에 담아 사용
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("111");
}
};
call(r1);
// 익명 클래스를 바로 사용
call(new Runnable() {
@Override
public void run() {
System.out.println("111");
}
});
/*
Thread(Runnable r) // Runnable : API 제공 인터페이스
*/
Thread t2 = new Thread(r1);
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("111");
}
});
/*
class B extends Test // 클래스 정의
{
int i = 1;
public void call() {}
}
Test t = new B(); // 객체 생성
-->
익명클래스 : 객체 생성 + 클래스 정의
Test t = new Test()
{
int i = 1;
public void call() {}
};
class Child1 extends Parent {
public void call() {}
}
Parent p = new Child1();
-->
Parent p = new Parent() {
public void call() {}
};
*/
Runnable r = new MyRunnable();
Thread t = new Thread(r);
// 익명 클래스 : 객체 생성, 재정의
Parent p = new Child();
p.call();
// new 상위클래스() { 클래스 재정의 } => 부모 클래스 재정의
Parent p2 = new Parent() { // => 부모클래스를 재정의한 익명(자식) 클래스가 됨
public void call() {
System.out.println("재정의함");
}
}; // p와 p2는 동일함.
p2.call();
// 익명클래스 형태
// new 상위클래스[인터페이스]( ) {
// 메서드 ..
// }
final int val = 100;
class InnerLocal {
public void call() {
// 메서드에 선언된 지역변수 중 final 변수만 접근 가능
System.out.println(val);
}
}
InnerLocal local = new InnerLocal();
}
public static void main(String[] args) {
Top top = new Top();
// innerMember : non-static class
Top.InnerMember innerMember = top.new InnerMember();
System.out.println(innerMember.val); // 100
System.out.println(Top.StaticMember.val2); // 200, static 변수만 접근
Top.StaticMember.call(); // StaticMember
Top.StaticMember innerStatic = new Top.StaticMember(); // static, non-statin 변수 모두 접근하기위해 객체 생성
System.out.println(innerStatic.val); // 100
System.out.println(Top.StaticMember.val2); // 200
// 인터페이스
System.out.println(TopInterface.Player.Address.addr); // 인터페이스의 주소
TopInterface.Player player = new TopInterface.Player() {
@Override
public void play() {
System.out.println("인터페이스 play");
}
@Override
public void call() {
System.out.println("인터페이스 call");
}
};
player.play(); // 인터페이스 play
player.call(); // 인터페이스 call
}
}
class Top {
String data;
static String data2;
class InnerMember { // Top 안에 있는 내부 클래스
int val = 100;
// static int val2 = 200; // 오류, static이 붙지 않은 내부 클래스는 static 변수 선언이 안됨
public void call() {
System.out.println("InnerMember");
}
public void getEnclosing() {
System.out.println(data); // 자기를 감싸고 있는 클래스내(외부클래스)에 선언된 일반 변수
System.out.println(data2); // 자기를 감싸고 있는 클래스내(외부클래스)에 선언된 스태틱 변수
}
}
static class StaticMember { // static 클래스
int val = 100;
static int val2 = 200; // static 클래스는 static 변수 선언 가능
public static void call() {
System.out.println("StaticMember");
}
public void getEnclosing() { // static 클래스내에서는 static 변수로만 접근 가능
// System.out.println(data); // non-static 접근 불가능
System.out.println(data2); // static 접근 가능
}
}
}
interface TopInterface { // 인터페이스내에 내부 인터페이스 선언 가능
static interface Player { // 자동으로 static 가 붙는다.
void play();
void call();
interface Address { // static 자동 생성
String addr = "인터페이스의 주소"; // public static final 자동 생성
// TopInterface.Plater.Address.addr
}
}
}
// 추상 클래스
abstract class Parent {
abstract public void call();
}
// 추상 클래스를 상속받은 자식 클래스
class Child extends Parent {
public void call() {
System.out.println("재정의함");
}
}
// Thread에서 사용되는 Runnable 클래스 재정의, 한번만 사용될 경우 내부클래스/익명클래스로 정의해서 사용
// new Runnable() { run 메서드 오버라이딩 };
/*
Runnable r = new Runnable() {
public void run() {
System.out.println("test");
}
};
*/
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("test");
}
}
결과
100
200
StaticMember
100
200
인터페이스의 주소
인터페이스 play
인터페이스 call
Java - 메이븐 프로젝트에서 ojdbc6 다운로드 안될때 (0) | 2020.01.21 |
---|---|
Java - 어노테이션 (Annotation) 활용위치와 사용시간 (0) | 2018.10.16 |
Java - 어노테이션 (Annotation) 멀티밸류 활용 (0) | 2018.10.16 |
Java - 어노테이션 (Annotation) 활용 (0) | 2018.10.15 |
Java - 어노테이션 (Annotation) (0) | 2018.10.12 |
댓글 영역