쿠릉쿠릉 쾅쾅
쿠릉쿠릉 쾅쾅
쿠릉쿠릉 쾅쾅
250x250
전체 방문자
오늘
어제
  • 분류 전체보기
    • HTML CSS
    • 잡담
    • 프로그래밍 꿀팁 사이트
    • 코딩 도서
    • [자바]
      • 디자인 패턴
      • 자바의 정석 - 3판
      • 자바
      • 자바 문법
    • git
    • [TDD]
    • 개발 서적 독후감
      • 클린 코더
      • 토비 스프링3
      • 객체지향의 사실과 오해
      • 모던 자바 인 액션
      • 엘레강트 오브젝트
    • CS
      • 운영체제
      • HTTP
    • [SQL]
      • SQL 기초
      • 혼자공부하는SQL
    • [ Spring ]
      • REST API
      • Spring Toy
      • Spring 에러
      • Spring
      • Spring 입문
      • Spring 핵심 원리
      • SpringMVC 1편
      • SpringMVC 2편
      • Spring Boot를 이용한 RESTful We..
      • Batch
    • [JPA]
      • JPA
      • JPA 에러
      • JPA 프로그래밍 - 기본편
      • 스프링 부트와 JPA 활용 1 - 웹 애플리케이..
      • 실전! 스프링 부트와 JPA 활용2 - API 개..
      • 실전! 스프링 데이터 JPA
      • 실전! Querydsl
    • 인텔리제이
    • [DB]
      • DB
      • H2
    • Gradle
    • 면접
    • [알고리즘]
      • 알고리즘
      • 자료구조
      • 자바 알고리즘 공부
    • [프로젝트]
    • 쿠릉식 객체지향 사고
    • 리눅스

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • GitHub
  • java
  • REST API
  • 스프링부트
  • querydsl
  • 깃허브
  • 알고리즘
  • 함수형인터페이스
  • 재귀
  • 자료구조
  • SQL
  • Git
  • springboot
  • 자바
  • http
  • 스프링
  • Spring
  • MVC
  • 백준
  • JPA

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
쿠릉쿠릉 쾅쾅

쿠릉쿠릉 쾅쾅

[Java] 내부 클래스, 네스티드(Nested) 클래스, 익명 클래스
[자바]/자바

[Java] 내부 클래스, 네스티드(Nested) 클래스, 익명 클래스

2022. 1. 27. 17:07
728x90

 

 

 

 

📍 학습목표
네스티드(Nested)클래스 대해서 알아보자

 

 

네스티드(Nested) 클래스 (내부 클래스)

  • 클래스 내에 정의되는 모든 클래스
  • 내부 클래스도 클래스이기 때문에 abstract나 final과 같은 제어자를 사용할 수 있다. 또, 멤버변수처럼 private, protected와 같은 접근제어자도 사용 가능하다.
  • 내부 클래스 중에서 static 클래스만 static 멤버를 가질 수 있다. 다만, final과 static이 동시에 붙은 변수는 상수(constant)이므로 모든 내부 클래스에서 정의가 가능하다.
  • 네스티드 클래스는 static의 선언 여부를 기준으로 나눌 수 있다.
    • Static 네스티드 클래스 (스태틱 클래스)
    • Non-static 네스티드 클래스 (이너(Inner) 클래스)
      • 멤버 클래스 (인스턴스 클래스)
      • 로컬 클래스 ( 지역 클래스)
      • 익명 클래스 (익명 클래스)

 

 

Static 네스티드 클래스

  • 외부 클래스의 멤버변수 선언위치에 선언하며, 외부 클래스의 static 멤버처럼 다뤄진다.
  • 주로 외부 클래스의 static 메서드와 static 변수와 작업한다.
  • Static 클래스는 외부 클래스의 인스턴스 변수와 메서드에 접근이 불가능하다.
더보기

예제

public  class Prac {	
	
    public static void main (String[] args) {    
    	
    	Outer.Nested1 nst1 = new Outer.Nested1();
    	nst1.add(5);
    	
    	Outer.Nested2 nst2 = new Outer.Nested2();
    	System.out.println(nst2.get());
    	
    }
    
}

class Outer {
	private static int num = 0;
	
	static class Nested1 {  // static 클래스
		void add(int n) {num += n;}
	}
	
	static class Nested2 {  // static 클래스
		int get() {return num;}
	}
	
}
5
  • Nested1 클래스와 Nested2 클래스는 Outer의 static 멤버 num에 접근하고 있다. num 멤버변수가 private로 선언되어 있어도 접근이 가능하다.
  • Static 클래스 내에는 외부 클래스의 static 멤버변수와 메소드에만 접근이 가능하다.

 

내부 클래스

  • 내부 클래스는 static이 붙지 않는 내부 클래스다.
  • 내부 클래스는 3가지 종류의 클래스로 나눌 수 있다.
    • 인스턴스 클래스
    • 지역 클래스
    • 익명 클래스

 

🔍 인스턴스 클래스

  • 외부 클래스의 인스턴스 변수, 인스턴스 메소드와 동일한 위치에 선언된다.
  • 외부 클래스의 인스턴스 멤버처럼 다뤄진다.
  • 주로 외부 클래스의 인스턴스 멤버들과 작업한다.
  • 클래스의 정의를 감춰야할 때 유용하게 사용한다.
더보기

예제

public  class Prac {	
	
    public static void main (String[] args) {    

    	Outer o1 = new Outer();
    	Outer o2 = new Outer();
    	
    	// o1 기반으로 두 인스턴스 생성
    	Outer.Member o1m1 = o1.new Member();
    	Outer.Member o1m2 = o1.new Member();

    	// o2 기반으로 두 인스턴스 생성
    	Outer.Member o2m1 = o2.new Member();
    	Outer.Member o2m2 = o2.new Member();
    	
    	// o1 기반으로 생성된 두 인스턴스의 메서드 호출
    	o1m1.add(5);
    	System.out.println(o1m1.get());
    	
    	// o2 기반으로 생성된 두 인스턴스의 메서드 호출
    	o2m1.add(7);
    	System.out.println(o2m1.get());
    	
    }
    
}

class Outer {
	private int num = 0;
	
	class Member {
		void add(int n) {num += n;}
		int get() {return num;}
	}
	
}
5
7
  • Member 클래스의 인스턴스는 외부 클래스의 인스턴스에 종속적이다.

 


 

예제2

public  class Prac {	
	
    public static void main (String[] args) {    
    	Papers p = new Papers("서류 출력");
    	Printable prn = p.getPrinter();
    	prn.print();
    }
}

interface Printable {
	void print();
}

class Papers {
	private String con;
	
	public Papers(String s) {con = s;}
	
	// 인스턴스 클래스 생성 및 반환
	public Printable getPrinter() {
		return new Printer();
	}
	
	//인스턴스 클래스 정의
	private class Printer implements Printable {
		public void print() {
			System.out.println(con);
		}
	}
	
}
서류 출력
  • Papers 클래스의 외부에서는 getPrinter() 메서드가 어떠한 인스턴스의 참조 값을 반환하는지 알지 못한다. 다만 반환되는 참조 값의 인스턴스가 Printable을 구현하고 있어서 Printable의 참조 타입으로 다룰 수 있다는 것만 알 수 있다. 이러한 상황을 '클래스의 정의가 감추어진 상황'이라고 한다.
  • 이렇게 클래스의 정의를 감추면, getPrinter() 메서드가 반환하는 인스턴스가 다른 클래스의 인스턴스로 변경되어도 Papers 클래스 외부의 코드는 조금도 수정할 필요가 없다. (코드에 유연성 추가)
  • Iterator<E> 인터페이스가 그런 예다.

 

 

🔍 지역 클래스 

  • 외부 클래스의 메서드나 초기화 블럭 안에 선언하며, 선언된 영역 내부에서만 사용될 수 있다.
  •  지역 클래스는 외부 클래스의 인스턴스 멤버와 static 멤버를 모두 사용할 수 있다.
  • 지역 클래스가 포함된 메서드에 정의된 지역변수도 사용할 수 있다. 단, final이 붙은 지역변수만 접근 가능하다
    • 메서드가 수행을 마쳐서 지역변수가 소멸된 시점에도, 지역 클래스의 인스턴스가 소멸된 지역변수를 참조하려는 경우가 발생할 수 있기 때문이다.
    • 메소드 내에서 생성된 객체는 메소드 실행이 끝나도 힙 메모리에 존재해서 계속 사용할 수 있다. 그러나 매개 변수나 지역 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 객체에서 사용할 수 없게 되는 문제가 발생한다.
    • JDK1.8부터 지역 클래스에서 접근하는 지역 변수 앞에 final을 생략할 수 있게 바뀌었다. 대신 컴파일러가 자동으로 붙여준다. 만약에 해당 변수의 값이 바뀌는 문장이 있으면 컴파일 에러가 발생한다.
더보기

예제

public  class Prac {	
	
    public static void main (String[] args) {    
    	Papers p = new Papers("서류 출력");
    	Printable prn = p.getPrinter();
    	prn.print();
    }
}

interface Printable {
	void print();
}

class Papers {
	private String con;
	
	public Papers(String s) {con = s;}
	
	// 지역 클래스 생성 및 반환
	public Printable getPrinter() {
		
		// 지역 클래스 정의
		class Printer implements Printable {
			public void print() {
				System.out.println(con);
			}
		}
		
		return new Printer();
		
	}
	
}
서류 출력
  • Printer 클래스가 getPrinter() 메서드 안에 선언되었다.
  • 이렇듯 메서드 내에 클래스를 정의하면 해당 메서드 내에서만 인스턴스 생성이 가능하다.
  • 인스턴스 클래스보다 클래스를 더 깊이, 특정 블록 안으로 감추는 효과가 있다.

 


 

예제2

class Inner {
	
	private int outerIv = 0;
	
	void myMethod() {
		int lv = 0;
		final int lv2 = 0;   // JDK1.8부터 final 생략 가능
		
		class LocalInner {
//			lv = 5;  // 에러.
			
		}
		lv=5;
		
	}
	
}
  • 외부 클래스의 메서드 내에서 정의된 지역 클래스는 final이 붙은 지역변수만 접근 가능하다. (JDK1.8부터 지역변수에 final 생략 가능)
  • 지역클래스인 LocalInner 클래스가 포함되고 있는 myMethod() 메서드의 지역변수를 참조하는 순간 해당 지역 변수는 final이 붙은 상수로 바뀐다. (final 생략 가능)

 

🔍 익명 클래스

  • 클래스의 선언과 객체의 생성을 동시에 하는 이름 없는 클래스다. (일회용)
  • 생성자를 선언할수도 없으며, 오로지 한 개의 클래스 또는 한 개의 인터페이스를 상속 받거나 구현할 수 있다.

 

💡 익명 클래스 정의 2가지 방법

new 조상클래스() {
    // 멤버 선언
};
new 인터페이스() {
    // 멤버 선언
};

 

더보기

예제

public  class Prac {	
	
    public static void main (String[] args) {    
    	Papers p = new Papers("서류 출력");
    	Printable prn = p.getPrinter();
    	prn.print();
    }
}

interface Printable {
	void print();
}

class Papers {
	private String con;
	
	public Papers(String s) {con = s;}
	
	// 지역 클래스 생성 및 반환
	public Printable getPrinter() {
		
		return new Printable() {
			public void print() {System.out.println(con);};
		};
		
	}
	
}
서류 출력
  • getPrinter() 메서드 안에 지역 클래스를 선언하지 않고 익명 클래스로 선언하였다.

 

 

 

 

 

728x90

'[자바] > 자바' 카테고리의 다른 글

[Java] Optional<T> 클래스  (0) 2022.02.07
[Java] 메서드 참조 (Method References)  (0) 2022.02.04
[Java] 함수형 인터페이스  (0) 2022.02.03
[Java] 애노테이션 (annotation)  (0) 2022.01.26
[Java] 열거형 (enum)  (0) 2022.01.26
    '[자바]/자바' 카테고리의 다른 글
    • [Java] 메서드 참조 (Method References)
    • [Java] 함수형 인터페이스
    • [Java] 애노테이션 (annotation)
    • [Java] 열거형 (enum)
    쿠릉쿠릉 쾅쾅
    쿠릉쿠릉 쾅쾅
    깃허브 주소 : https://github.com/kureung

    티스토리툴바