학습할 것
· Nested Class란?
· Static nested 클래스
- StaticNested 클래스 객체 생성
- StaticNested 클래스의 사용이유
· 내부(inner or local inner) 클래스와 익명 클래스(anonymous)
- 내부 클래스
- 내부 클래스 객체 생성
- 내부 클래스의 사용이유
- 익명 클래스
· Static Nested 클래스와 내부 클래스에서 참조 가능한 변수
Nested Class란?
· 클래스 안에 들어있는 클래스
· 존재이유: 1. 한 곳에서만 사용되는 클래스를 논리적으로 묶어서 처리하기 위해
2. 캡슐화를 위해(내부 구현을 감추고 싶을 때) 3. 소스 가독성가 유지보수성을 높이기 위해
ex) 자바 기반의 UI 처리를 할 때 사용자 입력, 외부의 이벤트에 대한 처리
· Nested 클래스의 종류: Static nested class, inner class (local, anonymous)
Static nested 클래스
public class OuterOfStatic {
static class StaticNested{
private int value=0;
public int getValue(){
return value;
}
public void setValue(int value){
this.value=value;
}
}
}
· 위 코드를 컴파일하면, 내부의 Nested 클래스는 별도로 컴파일하지 않아도 자동으로 컴파일된다. 컴파일 결과↓
· 컴파일 결과를 보면 Nested 클래스를 감싸고 있는 이름 뒤에 $를 붙인 후 Nested 클래스의 이름이 나오고, 별도의 클래스 파일로 만들어진다.
StaticNested 클래스 객체 생성
감싸고 있는 클래스 이름 뒤체 .(점)을 찍고 사용
public class NestedClassClient {
public static void main(String[] args){
NestedClassClient client = new NestedClassClient();
client.makeStaticNestedObj();
}
public void makeStaticNestedObj(){
OuterOfStatic.StaticNested staticNested = new OuterOfStatic.StaticNested();
staticNested.setValue(3);
System.out.println(staticNested.getValue());
}
}
StaticNested 클래스의 사용이유
· 클래스를 묶기 위해 사용
· 겉 보기에는 유사하지만, 내부적으로 구현이 달라야할 때
· 예시: 하나의 프로그램에서 School 클래스, University 클래스, Student 클래스가 존재할 때 Student가 School의 학생인지 University의 학생인지 불분명해진다. 이럴 때 StaticNested 클래스를 사용할 수 있다.
public class University {
static class Student{
}
}
public class School {
static class Student{
}
}
내부(inner or local inner) 클래스와 익명 클래스(anonymous)
내부 클래스
· StaticNested 클래스에서 static 선언을 지운 형태
public class OuterOfInner {
class Inner{
private int value=0;
public int getValue(){
return value;
}
public void setValue(int value){
this.value=value;
}
}
}
내부 클래스 객체 생성
· Inner 클래스를 감싸는 Outer 클래스 객체를 먼저 생생한 후, 해당 outer 객체를 통해 Inner 클래스의 객체를 만듦
public class NestedClassClient {
public static void main(String[] args){
NestedClassClient client = new NestedClassClient();
client.makeInnerObject();
}
public void makeInnerObject(){
OuterOfInner outer = new OuterOfInner();
OuterOfInner.Inner inner = outer.new Inner();
inner.setValue(3);
System.out.println(3);
}
}
내부 클래스의 사용이유
· 캡슐화를 위해
· 하나의 클래스에서 어떤 공통적인 작업을 수행하는 클래스가 필요한데 다른 클래스에서는 그 클래스가 전혀 필요 없을 때
· 예시: GUI관련 프로그램 개발 (리스너, 버튼 클릭 또는 키보드 입력 등 이벤트 발생시 해야 하는 작업 정의)
익명 클래스
· 이름이 없는 클래스
예시 - 버튼 처리
public class MagicButton {
public MagicButton(){
}
private EventListener listener;
public void setListener(EventListener listener){
this.listener=listener;
}
public void onClickProcess(){
if(listener!=null){
listener.onClick();
}
}
}
public interface EventListener {
void onClick();
}
public class AnonymousClient {
public static void main(String args[]){
AnonymousClient client = new AnonymousClient();
client.setButtonListener();
}
public void setButtonListener(){
MagicButton button = new MagicButton();
button.setListener(new EventListener() {
@Override
public void onClick() {
System.out.println("Magic Button Cliecked");
}
});
button.onClickProcess();
}
}
· AnonymousClient 클래스의 setButtonListener() 메소드에서 button 객체의 setListener() 메소드를 보면, new EventListener()로 생성자를 호출한 후 바로 중괄호를 열어 onClick() 메소드를 구현했다. 이렇게 구현한 것이 익명 클래스다.
· 클래스 이름, 객체 이름이 없으므로 다른 클래스나 메소드에서 참조, 재사용 불가
· 익명 클래스의 장점: 메모리 사용량↓ , 애플리케이션 시작 시간↓ (클래스를 만들고, 호출하면 그 정보가 메모리에 올라가므로)
Static Nested 클래스와 내부 클래스에서 참조 가능한 변수
· Static Nested 클래스를 외부 클래스의 static 변수만 접근 가능하고, 내부 클래스는 외부 클래스의 모든 변수에 접근 가능하다.
public class NestedValueReference {
public int publicInt=0;
protected int protectedInt=1;
int justInt=2;
private int privateInt=3;
static int staticInt=4;
static class StaticNested{
public void setValue(){
staticInt=14;
}
}
class Inner{
public void setValue(){
publicInt=20;
protectedInt=21;
justInt=22;
privateInt=23;
staticInt=24;
}
}
public void setValue(){
EventListener listener = new EventListener() {
@Override
public void onClick() {
publicInt=20;
protectedInt=21;
justInt=22;
privateInt=23;
staticInt=24;
}
};
}
}
· 외부 클래스에서 Static Nested 클래스와 내부 클래스의 인스턴스 변수에 접근도 가능하다. private라고 해도 모두 접근할 수 있다.
public class ReferenceAtNested {
static class StaticNested{
private int staticNestedInt=99;
}
class Inner{
private int innerValue=100;
}
public void setValue(int value){
StaticNested nested = new StaticNested();
nested.staticNestedInt=value;
Inner inner=new Inner();
inner.innerValue=value;
}
}
출처
자바의신
'자바' 카테고리의 다른 글
[Java] 자바에서 문자열을 다루는 방법 - String (0) | 2021.08.28 |
---|---|
[Java] 자바의 예외처리 방법 (0) | 2021.08.27 |
[Java] JVM 메모리 사용 영역 (0) | 2021.08.20 |
[Java] 자바의 연산자 (0) | 2021.08.20 |
[Java] 자바 데이터 타입(자료형), 변수 그리고 배열 (0) | 2021.08.18 |
댓글