Java

Inner class(중첩 클래스)

H_u 2024. 5. 14. 11:45
728x90
반응형
SMALL

 💡 학습 목표

  1. 내부 클래스란? (inner class)
  2. 내부 클래스의 종류

 

 

1. 내부 클래스란? (inner class)

자바에서 내부 클래스(Inner Class)는 한 클래스 내부에 선언된 클래스를 말합니다. 내부 클래스를 선언하게 되면 내부 클래스와 외부 클래스라고 표현할 수 있습니다. 내부 클래스는 보통 외부 클래스와 연관이 있는 경우가 많고 다른 곳에서 거의 사용할 일이 없는 경우에 내부 클래스를 선언해서 활용을 합니다.

 

class OuterClass {

private int num = 10;

 

class InnerClass {

public void display() {

System.out.println("num: " + num);

}

}

}

 

public class Main {

public static void main(String[] args) {

OuterClass outer = new OuterClass();

OuterClass.InnerClass inner = outer.new InnerClass();

inner.display(); // 출력: num: 10

}

}

 

 

2. 내부 클래스의 종류

  1. 멤버 내부 클래스(Member Inner Class): 외부 클래스의 필드와 같은 위치에 선언되며, 외부 클래스의 인스턴스에 종속적입니다. 멤버 내부 클래스의 인스턴스는 외부 클래스의 인스턴스가 있어야 생성할 수 있습니다.
  2. 정적 내부 클래스(Static Inner Class): 외부 클래스의 필드에 선언되지만, static 키워드를 사용하여 선언됩니다. 정적 내부 클래스는 외부 클래스의 인스턴스와 독립적으로 존재할 수 있으며, 주로 관련 있는 클래스들을 논리적으로 그룹화할 때 사용됩니다.
  3. 지역 내부 클래스(Local Inner Class): 메서드 내부에 선언되며, 선언된 메서드 내에서만 사용됩니다. 지역 내부 클래스는 해당 메서드의 지역 변수와 마찬가지로 스코프가 제한됩니다.
  4. 익명 내부 클래스(Anonymous Inner Class): 이름이 없는 내부 클래스로, 주로 인터페이스나 추상 클래스를 간편하게 구현할 때 사용됩니다. 익명 내부 클래스는 오직 하나의 인스턴스만 생성할 수 있으며, 주로 이벤트 처리나 콜백 구현에 사용됩니다.

 

 

1. 멤버 내부 클래스

package useful.ch07;

 

class Book {

private String title;

private Author author;

 

// 생성자에서 책의 제목과 저자의 정보를 초기화

public Book(String title, String authorName, String authorEmail) {

this.title = title;

this.author = new Author(authorName, authorEmail);

}

 

public void printBookDetails() {

System.out.println("Book Title: " + title);

System.out.println("작가 이름 : " + author.name + ", 이메일 : " + author.email);

}

 

// 멤버 내부 클래스

class Author {

private String name;

private String email;

 

// 생성자에서 저자의 이름과 이메일을 초기화

public Author(String name, String email) {

this.name = name;

this.email = email;

}

}

}

 

 

 

package useful.ex06;

 

public class BookTest {

 

public static void main(String[] args) {

 

// 멤버 내부 클래스를 사용하는 설계 방식의 주요 이점

// 캡슐화를 강화

// - 내부적으로 어떤 기능이 있는지 숨길 수 있다

// 로직의 응집도 향상

// - 특정 기능이나 데이터를 사용하는 코드를 한 곳에 모으면,

// 코드의 응집도가 향상됩니다.

// 이는 코드를 이해하고 유지보수하기 쉽게 만들어 줍니다.

Book book = new Book("홍길동전", "허균", "허균@example.com");

book.printBookDetails();

 

// 외부에서 Book 안에 있는 내부클래스 Author에 쉽게 접근이 안됨

}

}

 

2. 정적 내부 클래스(Static Inner Class)

package useful.ch07;

 

public class Spaceship {

 

// 배열 - 이 우주선 설계는 엔진을 최대 3개 까지

// 장착할 수 있다.

private Engine innerEngine;

 

// 정적 내부 클래스 Engine

public static class Engine {

 

public static int engineCount = 0;

private int serialNumber;

 

public Engine() {

this.serialNumber = ++engineCount;

}

 

public void start() {

System.out.println("Engine " + serialNumber + " 동작 합니다. 부릉~~");

}

} // end of inner class

 

// 우주선에 엔진 추가

public void addEngine(Engine engine) {

innerEngine = engine;

System.out.println("엔진 : " + innerEngine.serialNumber + " 을 장착 합니다");

Engine.engineCount++;

}

 

public void startSpaceShip() {

if (innerEngine == null) {

System.out.println("엔진을 먼저 장착해주세요");

} else {

System.out.println("달나라로 출발 합니다 슈웅~");

}

}

 

} // end of class

 

 

package useful.ch07;

 

import useful.ch07.Spaceship.Engine;

 

public class SpaceshipTest {

 

public static void main(String[] args) {

 

Spaceship spaceship = new Spaceship();

spaceship.startSpaceShip();

 

// 외부에서 엔진을 만들어서

// spaceship 주입 시켜야 한다

 

Engine 누리호1번엔진 = new Engine();

Engine 누리호2번엔진 = new Spaceship.Engine();

Engine 누리호3번엔진 = new Spaceship.Engine();

 

// 변수명은 한글로 작성하지 말자 !!

System.out.println("--------------");

spaceship.addEngine(누리호3번엔진);

spaceship.startSpaceShip();

 

// 사용하는 이유

// [논리적인 그룹화]

// 정적 내부 클래스는 외부 클래스와 논리적으로

// 관련 있는 클래스들을 그룹화 하는데 유용하다.

 

}

 

}

 

 

 

3. 지역 내부 클래스(Local Inner Class)

public class OuterClass {

 

// 외부 클래스의 메서드

public void display() {

// 지역 내부 클래스

class LocalInnerClass {

void printMessage() {

System.out.println("Hello from the Local Inner Class!");

}

}

 

// 지역 내부 클래스의 인스턴스 생성

LocalInnerClass inner = new LocalInnerClass();

// 메서드 호출

inner.printMessage();

}

 

public static void main(String[] args) {

OuterClass outer = new OuterClass();

outer.display();

}

}

 

 

지역 내부 클래스는 특정 메서드 내에서만 정의되고 사용되는 클래스로, 메서드 실행 시에만 존재하고 메서드의 지역 변수처럼 동작합니다. 이 클래스는 외부에서는 접근할 수 없으며, 주로 메서드 내에서 일회성 작업을 수행하는 객체를 생성할 때 유용 합니다.

 

 

4. 익명 내부 클래스 (익명이란? 이름이 없다 라는 의미 입니다.)

package basic.useful.ch07;

/**

* 익명 내부클래스에 대해서 살펴 보자.

*/

public class Outter {

 

Runnable runable1; // 인터페이스 이다.

// 인터페이스는 기본적으로 객체를 만들 수 없다

// 하지면 익명 내부 클래스로 구현할 수 있다.

// 이런것들을 앞으로 우리는 구현 클래스라 부르자

 

public Outter() {

// Runnable 인터페이스를 구현 클래스로 만들었다.

// Outter 클래스 내부에 있고, 이녀석을 만들었지만

// 다른곳에서 부를 방법이 없다. 이름이 없음 - 익명

// 종합 하면 익명 내부 클래스 명칭 한다.

new Runnable() {

public void run() {

// ...

}

};

}

 

// 변수에 Runnable 구현 클래스 대입

Runnable runner = new Runnable() {

@Override

public void run() {

System.out.println("Runnable 이 구현된 익명 클래스 변수");

 

}

};

 

// 리턴 타입으로 Runnable 구현 클래스 반환

Runnable getRunnable(int i) {

 

int num = 100;

 

return new Runnable() {

@Override

public void run() {

// num = 200; //에러 남

// i = 10; //에러 남

System.out.println(i);

System.out.println(num);

 

}

};

}

}

728x90
반응형
SMALL

'Java' 카테고리의 다른 글

문자 기반 스트림  (0) 2024.05.17
파일 Copy (바이트기반 입/출력)  (0) 2024.05.16
표준 입출력이란?  (0) 2024.05.14
자바 I/O 개론  (0) 2024.05.14
파일 입력 스트림(바이트 기반)  (0) 2024.05.14