2020. 4. 27. 21:34ㆍ인프런/웹개발 코스 [JAVA 개발언어]
내부 클래스
내부 클래스란 클래스 내에 선언된 클래스입니다. 여기서 클래스에 다른 클래스를 선언하는 이유는 두 클래스가 서로 긴밀한 관계에 있기 때문입니다. 그렇기에 내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있고 코드의 복잡성을 줄여줍니다.
//외부 클래스
Class A{
// ...
//내부 클래스
Class b{
// ...
}
}
위의 코드에서 B는 A의 내부 클래스가 되고 A는 B의 바깥에 있는 외부클래스가 됩니다 이때 내부 클래스인 B는 외부 클래스인 A를 제외하고는 다른 클래스에서 사용하지 않는 것이 좋습니다.(외부 클래스가 아닌 다른 클래스에서 내부 클래스에 접근해야 한다면 내부 클래스로 선언해서는 안 되는 클래스를 내부 클래스에 선언한 것과 같기때문)
내부 클래스의 종류와 특징
내부클래스 선언
package java01_01;
class Outer{
class InstanceInner{}//인스턴스 클래스
static class StaticInner{}//스태틱 클래스
void method1() {
class LocalInner{}//지역 클래스
}
}
각 내부 클래스의 선언 위치에 따라 같은 선언 위치의 변수와 동일한 유효 범위와 접근성을 갖습니다.
내부 클래스의 제어자와 접근성
package java01_01;
class Outer{
private class InstanceInner{}
protected static class StaticInner{}
void method1() {
class LocalInner{}
}
}
내부 클래스는 외부 클래스의 멤버와 같이 간주되고 인스턴스 맴버와 static맴버 간의 규칙이 내부 클래스에도 똑같이 적용이됩니다 그리고 내부 클래스도 클래스 이기 때문에 맴버 변수들처럼 privte protected와 같은 접근 제어자를 사용할 수 있습니다. 그리고 내부 클래스 중에서 스태틱 클래스만 static멤버를 가질 수 있으며 드문 경우지만 내부 클래에 static변수를 선언해야 한다면 static클래스로 선언해야 합니다.
내부 클래스중에서 스태틱 클래스(Static class)만 Static맴버를 가질수 있습니다 드문 경우지만 내부 클레스에 Static변수를 선언해야한담ㄴ 스텍틱 클래스로 선언해 주어야 합니다 다만 final과 static이 동시에 붙은 변수는 상수 이므로 모즌 내부 클래스에서 정의가 가능합니다
package java01_01;
class javatest2 {
class InstanceInner{}//인스턴스 클래스(내부)
static class StaticInner{}//스태틱 클래스(내부)
//인스턴스 맴버 간에는 서로 직접 접근가능
InstanceInner iv = new InstanceInner();
//static 맴버 간에도 서로 직접 접근가능
static StaticInner sv = new StaticInner();
static void staticMethod() {
//static맴버는 인스턴스 맴버에 직접 접근할수 없습니다
//InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
//접근하려면 아래와 같이 객체를 생성 해야합니다.
//인스턴스 클래스는 외부 클래스를 먼저 생성 해야만 생성할수 있습니다.
javatest2 outer = new javatest2();
InstanceInner obj1 = outer.new InstanceInner();
}
void instanceMethod() {
//인스턴스 메서드에서는 인스턴스 맴버와 static맴버 모드 접근이 가능합니다.
InstanceInner obj1 = new InstanceInner();
StaticInner obj2 = new StaticInner();
//메서드 내에 지역적으로 선언된 내부 클래스는 외부에서 접근할수 없습니다
//LocalInner lv = new LocalInner();
}
void method1() {
class LocalInner{}
LocalInner lv = new LocalInner();
}
}
인스턴스 클래스는 외부 클래스의 인스턴스 멤버를 객체 생성 없이 바로 사용할 수 있지만 스태틱 클래스는 외부 클래스의 인스턴스 맴버를 객체 생성 없이 사용할 수 없습니다 또한 인스턴스 클래스는 스태틱 클래스의 멤버들을 객체 생성없이 사용할수는 있지만 스태틱 클래스 에서는 인스턴스 클래스의 맴버들을 객체 생성 없이 사용할 수 없습니다.
package java01_01;
class javatest2 {
private int outerIv = 0;
static int outerCv = 0;
class InstanceInner{
int iiv = outerIv; //내부 클래스에서 외부클래스의 private맴버도 접근이 가능합니다
int iiv2 = outerCv;
}
static class StaticInner{
//스태틱 클래스는 외부 클래스의 인스턴스맴버에 접근할 수 없습니다.
//int iiv = outerIv;
static int scv = outerCv;
}
void method1() {
final int LV = 0
class LocalInner{
int liv = outerIv;
int liv2 = outerCv;
int liv4 = LV;
}
}
}
- 인스턴스 클래스는 외부의 클래스의 인스턴스 멤버이기 때문에 인스턴스 변수 outerlv와 static변수 outerCv를 모두 사용할 수 있습니다 그리고 outerlv의 접근자가 private일지라도 사용 가능합니다.
- 스태틱 클래스는 외부 클래스의 멤버기 때문에 외부 클래스의 인스턴스 멤버인outerlv와 InstanceInner를 사용할 수 없고 static맴버인 outerCv만을 사용할수 있습니다.
- 지역 클래스는 외부 클래스의 인스턴스 멤버와 static멤버 모두 사용할 수 있으며 지역 클래스가 포함된 메서드에 정의된 지역 분수도 final이 붙은 지역변수면 접근이 가능합니다.
- JDk1.8부터 지역 클래스에서 접근하는 지역 변수 앞에 final을 생략 할수 있습니다 컴파일러가 자동으로 붙여주는 것뿐이라 해당 변수의 값이 바뀌는 문장이 있다면 컴파일 에러가 발생합니다.
class javatest2 {
void method1() {
class LocalInner{}
}
void method2(){
class LocalInner{}
}
내부 클래스가 컴파일이 되면 클래스 파일명이 "외부 클래스명$내부 클래스명.class"형식으로 됩니다 다만 서로 다른 메서드 내에서 같은 이름의 지역변수를 사용하는 것이 가능한 것처럼 지역 내부 클래스는 다른 메서드에 같은 이름의 내부 클래스가 존재할 수 있기 때문에 내부 클래스명 앞에 숫자가 붙습니다.
위의 코드를 컴파일하면 javatest1.class, javatest1$1LocalInner.class, javatest1$2LocalInner.class인 3개의 클래스 파일이 생성됩니다.
class javatest2 {
int value = 10;
class Inner{
int value = 20;
void method() {
int value = 30;
System.out.println("value : "+ value);
System.out.println("this.value : "+ this.value);
System.out.println("Outer.this.value : "+ javatest2.this.value);
}
}
}
class test{
public static void main(String[] args) {
javatest2 javatt1 = new javatest2();
javatest2.Inner inner = javatt1.new Inner();
inner.method();
}
}
내부 클래스와 외부 클래스에 언언된 변수의 이름이 같을때 변수 앞에 this또는 외부 클래스명.this를 붙여서 구별할 수 있습니다.
익명 클래스
//사용방법1
new 부모클래스의 이름() {
//맴버 선언
}
//사용방법2
new 구현인터페이스 이름() {
//맴버 선언
}
익명 클래스는 클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한 번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 일회용 클래스입니다 이름이 없기 때문에 생성자를 가질 수 없으며 부모 클래스의 이름이나 구현하고자 하는 인터 페이스의 이름을 사용해서 정의하기 때문에 하나의 클래스로 상속받는 동시에 인터페이스를 구현하거나 둘 이상의 인터 페이스를 구현할 수 없습니다. 오로지 단 하나의 클래스를 상속받거나 단하나의 인터페이스만을 구현할수 있습니다.
class test{
Object iv = new Object() {void method(){}};
static Object cv = new Object() {void method(){}};
void method() {
Object lv = new Object() {void method(){}};
}
}
익명 클래스는 이름이 없기 떄문에 "외부 클래스명$숫자.class"의 형식으로 클래스 파일명이 결정이됩니다 그래서 위의 코드를 컴파일하면 test.class외에 test$1.class, test$2.class, test$3.class 라는 3개의 클래스 파일이 생성됩니다.
'인프런 > 웹개발 코스 [JAVA 개발언어]' 카테고리의 다른 글
Collection (0) | 2020.04.28 |
---|---|
열거형 (0) | 2020.04.27 |
인터페이스 (0) | 2020.04.27 |
추상화 (0) | 2020.04.27 |
다형성 (0) | 2020.04.27 |