본문 바로가기
휴먼 IT 교육 수업 메모

[휴먼IT] 휴먼IT 자바 수업 6일차 메모 (상속) 250109

by demianpark127 2025. 1. 9.
SMALL

package Class;

import java.text.DecimalFormat;
import java.util.InputMismatchException;
import java.util.Scanner;

// 하나의 java파일에 여러개의 클래스를 작성할 경우 반드시 하나의 public class가 존재해야한다.

//설계도 클래스
class Calcul {
	void cal (int x, int y) {
		System.out.println("사칙연산을 시작합니다");
	}
}

//더하기
class Add extends Calcul{	
	@Override
	void cal (int x, int y) {
		System.out.println(x+"+"+y+"="+(x+y));
	}
}
//빼기
class Sub extends Calcul{
	@Override
	void cal (int x, int y) {
		System.out.println(x+"-"+y+"="+(x-y));
	}
}
//곱하기
class Mul extends Calcul{
	@Override
	void cal (int x, int y) {
		System.out.println(x+"*"+y+"="+(x*y));
	}
}

//나누기
class Div extends Calcul{
	@Override
	void cal (int x, int y) {
		if (y == 0) {
            System.out.println("0으로 나눌 수 없습니다.");
            return;
        }
        // 출력1
        System.out.printf("%d / %d = %.2f\n", x, y, ((float) x / (float) y));

        // 출력2
        DecimalFormat df = new DecimalFormat("#,###.##");
        double v = x / (double) y;
        System.out.println(x + "/" + y + "=" + df.format(v));
    }
}


public class C6_오버라이딩 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String op = null;
		int x=0, y=0;
		Calcul ct = new Calcul();		
		
		while(true) {
			System.out.println("=====================");
			System.out.println("입력폼 예시 : 숫자 + 숫자");
			System.out.println("연산자종류 선택(+,-,*,/)>>");
			
			try {				
				System.out.print("x>> ");
				x = Integer.parseInt(sc.next());
				System.out.print("op>> ");
				op = sc.next();
				System.out.print("y>> ");
				y = Integer.parseInt(sc.next());
				
				//다형성구현 - 오버라이딩구현
				if(op.equals("+")) {
					//업캐스팅
					ct = new Add(); // 부모 = 자식	
				}else if(op.equals("-")) {
					ct = new Sub();
				}else if(op.equals("*")) {
					ct = new Mul();
				}else if(op.equals("/")) {
					ct = new Div();
				}else {
					System.out.println("잘못 입력하셨습니다.");
					continue;
				}		
				
				ct.cal(x, y);
				
			} catch (NumberFormatException e) {
                System.out.println("숫자를 올바르게 입력해주세요.");
                sc.nextLine(); // 버퍼 비우기
            } catch (Exception e) {
                System.out.println("오류가 발생했습니다: " + e.getMessage());
            }
			
			System.out.println("계속 하시겠습니까?(y/n)");
			String answer = sc.next();
			
			if(answer.equals("n")) {
				sc.close();
				System.out.println("프로그램을 종료합니다...");
				break;
			}
		}
		
	}
}
=====================
입력폼 예시 : 숫자 + 숫자
연산자종류 선택(+,-,*,/)>>
x>> 10
op>> /
y>> 5
10 / 5 = 2.00
10/5=2
계속 하시겠습니까?(y/n)
n
프로그램을 종료합니다...

 

package Class;

/*
 						car - move()
 						 |
 						 |
 		-----------------------------------------
 		|		 |				|	 			|		
 		Bus		Ambulance		Tax				?
 		name	name			name			name
 		move()	move()			move()			move()
 		...()	...()			...()			...()
 
 
 
 */

public class C7_다형성실습 {
	public static void main(String[] args) {
		/*
		 	1. 자동차 배열 4개를 만든다
		 	2. 배열에 버스,엠뷸런스,택시,화차물 객체를 저장한다
		 		* 업캐스팅해서 저장해 둔다
		 		c = new Bus();
		 	3. 확장 for를 활용해서
		 		if(객체 instanceof 클래스) {
		 			. 재정의한 메서드 실행
		 			. 내것만의 메서드 실행
		 		}
		 */
	}

}

 

package 상속;

import bak.EE;

//private
class AA{
	private String name = "홍길동";
	private int age = 30;
	
	private void methodA() {
		System.out.println("A클래스-methodA입니다");
		System.out.println(name);
		System.out.println(age);
		
		methodB();		
	}
	void methodB() {			
		System.out.println("A클래스-methodB입니다");
	}
	

}
//default
class BB{
	String name = "홍길동";
	int age = 30;
	
	void methodA() {
		System.out.println("B클래스-methodA입니다");
		System.out.println(name);
		System.out.println(age);		
		methodB();
	}
	void methodB() {			
		System.out.println("B클래스-methodB입니다");
	}
		
}
//protected
class CC{
	protected String name = "홍길동";
	protected int age = 30;
	
	void methodA() {
		System.out.println("C클래스-methodA입니다");
		System.out.println(name);
		System.out.println(age);		
		methodB();
	}
	void methodB() {			
		System.out.println("C클래스-methodB입니다");
	}
}
//public
class DD{
	
}


public class Ext_3_접근제한자 {
	public static void main(String[] args) {
		//private
		AA a = new AA();
		//String name = a.name;
		//int age = a.age;
		//a.methodA();
		//a.methodB();
		
		//default
		BB b = new BB();
		String name1 = b.name;
		int age = b.age;
		b.methodA();
		b.methodB();
		
		//protected
		CC c = new CC();
		String name2 = c.name;
		int age2 = age;
		c.methodA();
		c.methodB();
		
		
		//private
		EE e = new EE();
		String name = e.name;
	
	}

}

 

package bak;

import 상속.FF;

/*
 	설령 상속관계라 하더라도
 	패키지가 다르다면... protected이상으로 지정되어야 한다
 */

public class EE extends FF {
	protected String address = "서울";
	//int age = 40;
	
	protected void methodE() {
		System.out.println("E클래스 입니다");
		
		String name = super.name; //부모의 멤버변수 - protected
		int age = super.age; //부모의 멤버변수 - public
		
	}
}
package 상속;

public class FF {	
	protected String name = "홍길동";
	public int age = 30;
	
	void methodA() {
		System.out.println("F클래스-methodA입니다");
		System.out.println(name);
		System.out.println(age);		
		methodB();
	}
	void methodB() {			
		System.out.println("F클래스-methodB입니다");
	}

}

 

추상 클래스란?

추상 클래스는 클래스 설계에서 **구체적으로 구현되지 않은 메서드(추상 메서드)**를 포함하는 클래스로, 하위 클래스에서 반드시 구현해야 할 메서드를 정의하는 데 사용됩니다. 추상 클래스는 설계도를 제공하면서도 일부 공통 기능은 구현할 수 있는 특징이 있습니다.


특징

  1. 추상 메서드 포함:
    • 추상 메서드는 구현되지 않은 메서드로, 선언만 하고 내용(구현부)을 작성하지 않습니다.
    • 하위 클래스에서 반드시 구현해야 합니다.
    • abstract class Shape {
          abstract void draw(); // 추상 메서드
      }
     
  2. 객체 생성 불가:
    • 추상 클래스 자체로는 객체를 생성할 수 없습니다.
    • 반드시 하위 클래스에서 상속받아 구체적으로 구현한 후 객체를 생성해야 합니다.
  3. 일반 메서드와 변수 포함 가능:
    • 추상 클래스는 일반 메서드나 변수를 포함할 수 있어, 공통 동작이나 데이터를 정의할 수 있습니다.
    • abstract class Animal {
          void eat() {
              System.out.println("This animal eats food.");
          }
      }
     
  4. 다형성 지원:
    • 추상 클래스는 **다형성(Polymorphism)**을 활용하는 데 유용합니다.
    • 동일한 타입(추상 클래스 참조 변수)으로 다양한 하위 클래스의 객체를 처리할 수 있습니다.

문법

추상 클래스 선언 

abstract class 클래스명 {
    // 추상 메서드
    abstract 반환타입 메서드명(매개변수);

    // 일반 메서드
    반환타입 메서드명(매개변수) {
        // 구현 내용
    }
}

 

추상 클래스 상속 및 구현

abstract class Shape {
    abstract void draw(); // 추상 메서드
}

class Circle extends Shape {
    @Override
    void draw() {
        System.out.println("Draw a circle");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape shape = new Circle(); // 다형성
        shape.draw(); // Draw a circle
    }
}

추상 클래스 vs 인터페이스

특징                 추상 클래스                                                           인터페이스

목적 클래스 설계도와 기본 구현 제공 완전한 설계도 제공
메서드 추상 메서드 + 일반 메서드 포함 가능 Java 8 이전: 추상 메서드만 포함
Java 8 이후: 디폴트 메서드, static 메서드 지원
다중 상속 다중 상속 불가능 다중 상속 가능
변수 일반 변수와 상수를 가질 수 있음 상수만 선언 가능
객체 생성 직접 생성 불가 직접 생성 불가
키워드 abstract interface

추상 클래스 활용 예

// 추상 클래스: 동물
abstract class Animal {
    abstract void sound(); // 추상 메서드
    void eat() {
        System.out.println("This animal eats food.");
    }
}

// 하위 클래스: 개
class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Woof Woof");
    }
}

// 하위 클래스: 고양이
class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Meow Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog(); // 다형성
        dog.sound(); // Woof Woof
        dog.eat();   // This animal eats food.

        Animal cat = new Cat(); // 다형성
        cat.sound(); // Meow Meow
        cat.eat();   // This animal eats food.
    }
}

추상 클래스의 장점

  1. 설계와 구현 분리:
    • 공통적인 기능은 추상 클래스에서 구현하고, 세부 사항은 하위 클래스에서 구현.
  2. 유지보수 용이:
    • 변경 시 공통 로직은 추상 클래스에서만 수정하면 되므로 유지보수가 간편.
  3. 다형성 활용:
    • 동일한 추상 클래스 타입으로 다양한 객체를 처리 가능.

추상 클래스는 코드 재사용성과 유연성을 높이는 강력한 도구로, 설계 단계에서 큰 도움을 줍니다.

package 추상클래스;

abstract class 동물{
	
	abstract void 걷기();
	abstract void 울기();
	abstract void 싸움();
}

class 강아지 extends 동물{

	@Override
	void 걷기() {		
	}

	@Override
	void 울기() {		
	}

	@Override
	void 싸움() {		
	}
	
}

class 고양이 extends 동물{
	
	String name;

	@Override
	void 걷기() {		
	}

	@Override
	void 울기() {		
	}

	@Override
	void 싸움() {		
	}	
}

class 병아리 extends 동물{

	@Override
	void 걷기() {		
	}

	@Override
	void 울기() {		
	}

	@Override
	void 싸움() {		
	}
	
}

public class Ab1_동물Ex {
	public static void main(String[] args) {
		강아지 진주 = new 강아지();
		
	}
}

인터페이스란?

자바에서 **인터페이스(Interface)**는 클래스의 설계도를 제공하는 특별한 타입으로, **구현되지 않은 메서드(추상 메서드)**와 상수만 포함할 수 있습니다. 인터페이스는 다중 상속을 지원하며, 클래스 간의 계약(Contract) 역할을 합니다.


특징

  1. 추상 메서드와 상수만 포함(Java 7까지):
    • 모든 메서드는 public abstract이며, 구현부가 없습니다.
    • 모든 변수는 public static final(상수)로 선언됩니다.
    • 선언 시 생략 가능하며, 자바가 자동으로 처리합니다.
  2. Java 8 이후 새로운 기능:
    • 디폴트 메서드(default method):
      • 구현부가 있는 메서드를 포함할 수 있습니다.
      • 인터페이스의 하위 호환성을 유지하면서 기능 확장이 가능합니다.
    • 정적 메서드(static method):
      • 정적 메서드를 포함할 수 있습니다.
      • 객체 생성 없이 인터페이스 이름으로 호출 가능합니다.
  3. Java 9 이후 새로운 기능:
    • private 메서드:
      • 인터페이스 내에서 디폴트 메서드나 정적 메서드의 공통 로직을 처리하기 위해 사용됩니다.
  4. 다중 상속 가능:
    • 인터페이스는 여러 개를 **구현(implement)**할 수 있습니다.
    • 이를 통해 다중 상속 문제를 해결할 수 있습니다.
  5. 객체 생성 불가:
    • 인터페이스는 객체를 생성할 수 없습니다.
    • 구현한 클래스를 통해서만 사용할 수 있습니다.

문법

인터페이스 선언

public interface 인터페이스명 {
    // 추상 메서드
    void 메서드명();

    // 디폴트 메서드 (Java 8+)
    default void defaultMethod() {
        System.out.println("This is a default method.");
    }

    // 정적 메서드 (Java 8+)
    static void staticMethod() {
        System.out.println("This is a static method.");
    }
}

인터페이스 구현

  • implements 키워드를 사용하여 구현.
public class 클래스명 implements 인터페이스명 {
    @Override
    public void 메서드명() {
        // 메서드 구현
    }
}

예제

기본 인터페이스

interface Animal {
    void sound(); // 추상 메서드

    default void eat() { // 디폴트 메서드
        System.out.println("This animal eats food.");
    }

    static void info() { // 정적 메서드
        System.out.println("This is an Animal interface.");
    }
}

class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("Woof Woof");
    }
}

class Cat implements Animal {
    @Override
    public void sound() {
        System.out.println("Meow Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.sound(); // Woof Woof
        dog.eat();   // This animal eats food.

        Animal cat = new Cat();
        cat.sound(); // Meow Meow
        cat.eat();   // This animal eats food.

        Animal.info(); // This is an Animal interface.
    }
}

다중 인터페이스 구현

다중 구현

interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    @Override
    public void fly() {
        System.out.println("The duck is flying.");
    }

    @Override
    public void swim() {
        System.out.println("The duck is swimming.");
    }
}

public class Main {
    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.fly();  // The duck is flying.
        duck.swim(); // The duck is swimming.
    }
}

장점

  1. 다중 상속 지원:
    • 여러 인터페이스를 구현하여 다양한 기능을 조합할 수 있습니다.
  2. 표준화된 설계 제공:
    • 인터페이스를 통해 구현 클래스의 공통 동작을 정의하고 강제할 수 있습니다.
  3. 유연성 향상:
    • 코드의 결합도를 낮추고 유연한 설계를 가능하게 합니다.

활용 예: 전략 패턴

인터페이스는 디자인 패턴(특히 전략 패턴) 구현 시 자주 사용됩니다.

interface Strategy {
    void execute();
}

class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        System.out.println("Strategy A executed.");
    }
}

class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        System.out.println("Strategy B executed.");
    }
}

class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void setStrategy(Strategy strategy) {
        this.strategy = strategy;
    }

    public void executeStrategy() {
        strategy.execute();
    }
}

public class Main {
    public static void main(String[] args) {
        Context context = new Context(new ConcreteStrategyA());
        context.executeStrategy(); // Strategy A executed.

        context.setStrategy(new ConcreteStrategyB());
        context.executeStrategy(); // Strategy B executed.
    }
}

 

package 인터페이스;

public class RobotEx {
	
	static void action(Robot r) {
		if(r instanceof DanseRobot) {
			((DanseRobot) r).dance();
		}else if(r instanceof DrawRobot) {
			((DrawRobot) r).draw();
		}else {
			((SingRobot) r).sing();
		}
	}
	
	public static void main(String[] args) {
		//부모를 담는 객체배열
		Robot[] rb = new Robot[3];
		
		//업캐스팅
		rb[0] = new DanseRobot();
		rb[1] = new DrawRobot();
		rb[2] = new SingRobot();
		
		//출력
		for(Robot r:rb) {
			action(r);
		}
	}
}
package 인터페이스;

public interface Robot {
	
}

class DanseRobot implements Robot{
	void dance() {
		System.out.println("춤을 춥니다");
	}
}
class DrawRobot implements Robot{
	void draw() {
		System.out.println("그림을 그립니다");
	}
}

class SingRobot implements Robot{
	void sing() {
		System.out.println("노래를 부릅니다");
	}		
}
package 인터페이스;

// 인터페이스 R
interface R {
    void connect(); // 연결 메서드
}

// 인터페이스 T
interface T {
    void disconnect(); // 연결 해제 메서드
}

// Speaker 인터페이스 (R과 T 상속)
public interface Speaker extends R, T {
    void volumeUp();   // 볼륨 올리기
    void volumeDown(); // 볼륨 내리기
}

// Tv 클래스
class Tv implements Speaker {
    private int volume = 10; // 볼륨 초기값

    @Override
    public void volumeUp() {
        if (volume < 100) {
            volume++;
            System.out.println("TV 볼륨 증가: " + volume);
        } else {
            System.out.println("TV 볼륨은 최대입니다.");
        }
    }

    @Override
    public void volumeDown() {
        if (volume > 0) {
            volume--;
            System.out.println("TV 볼륨 감소: " + volume);
        } else {
            System.out.println("TV 볼륨은 최소입니다.");
        }
    }

    @Override
    public void connect() {
        System.out.println("TV 연결되었습니다.");
    }

    @Override
    public void disconnect() {
        System.out.println("TV 연결 해제되었습니다.");
    }
}

// Audio 클래스
class Audio implements Speaker {
    private int volume = 15; // 볼륨 초기값

    @Override
    public void volumeUp() {
        if (volume < 50) {
            volume++;
            System.out.println("오디오 볼륨 증가: " + volume);
        } else {
            System.out.println("오디오 볼륨은 최대입니다.");
        }
    }

    @Override
    public void volumeDown() {
        if (volume > 0) {
            volume--;
            System.out.println("오디오 볼륨 감소: " + volume);
        } else {
            System.out.println("오디오 볼륨은 최소입니다.");
        }
    }

    @Override
    public void connect() {
        System.out.println("오디오 연결되었습니다.");
    }

    @Override
    public void disconnect() {
        System.out.println("오디오 연결 해제되었습니다.");
    }
}

// Phone 클래스
class Phone implements Speaker {
    private int volume = 5; // 볼륨 초기값

    @Override
    public void volumeUp() {
        if (volume < 20) {
            volume++;
            System.out.println("폰 볼륨 증가: " + volume);
        } else {
            System.out.println("폰 볼륨은 최대입니다.");
        }
    }

    @Override
    public void volumeDown() {
        if (volume > 0) {
            volume--;
            System.out.println("폰 볼륨 감소: " + volume);
        } else {
            System.out.println("폰 볼륨은 최소입니다.");
        }
    }

    @Override
    public void connect() {
        System.out.println("폰 연결되었습니다.");
    }

    @Override
    public void disconnect() {
        System.out.println("폰 연결 해제되었습니다.");
    }
}
package 인터페이스;

public class SpeakerEx {
    public static void main(String[] args) {
        // 스피커 객체 배열 생성 및 초기화
        Speaker[] speakers = new Speaker[3];
        speakers[0] = new Tv();       // TV 객체
        speakers[1] = new Audio();   // Audio 객체
        speakers[2] = new Phone();   // Phone 객체

        // 반복문으로 모든 객체의 volumeUp, volumeDown 실행
        for (Speaker speaker : speakers) {
            System.out.println("=== 스피커 동작 시작 ===");
            speaker.connect();       // 연결
            speaker.volumeUp();      // 볼륨 증가
            speaker.volumeDown();    // 볼륨 감소
            speaker.disconnect();    // 연결 해제
            System.out.println("=== 스피커 동작 종료 ===\n");
        }
    }
}

중첩 클래스(Nested Class)란?

자바에서 **중첩 클래스(Nested Class)**는 하나의 클래스 내부에 정의된 또 다른 클래스를 의미합니다. 중첩 클래스는 외부 클래스와 강하게 연관되어 있으며, 주로 외부 클래스와의 관계를 표현하거나 특정 논리적 그룹화를 위해 사용됩니다.


중첩 클래스의 종류

  1. 정적 중첩 클래스 (Static Nested Class)
    • 외부 클래스의 인스턴스 없이도 사용 가능한 클래스.
    • 외부 클래스와의 관계가 약한 경우 적합.
    • static 키워드로 선언.
    • 정적 멤버(static variables, methods)를 가질 수 있음.
  2. 비정적 중첩 클래스 (Non-Static Nested Class, Inner Class)
    • 외부 클래스의 인스턴스와 연관된 클래스.
    • 외부 클래스의 멤버(필드, 메서드)에 쉽게 접근 가능.
    • static 키워드 없이 선언.
  3. 지역 중첩 클래스 (Local Inner Class)
    • 메서드 내부에 정의된 클래스.
    • 메서드가 실행될 때만 사용 가능.
    • 외부 클래스의 멤버와 메서드의 지역 변수(필요시 final)에 접근 가능.
  4. 익명 중첩 클래스 (Anonymous Inner Class)
    • 이름이 없는 클래스.
    • 주로 인터페이스나 추상 클래스를 구현하거나 상속받아 1회성으로 사용.
    • 람다 표현식 이전에는 이벤트 리스너 등의 구현에 주로 사용됨.

정적 중첩 클래스 예제

class OuterClass {
    static class StaticNestedClass {
        void display() {
            System.out.println("정적 중첩 클래스");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // 정적 중첩 클래스는 외부 클래스의 인스턴스 없이 객체 생성 가능
        OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();
        nested.display(); // 정적 중첩 클래스
    }
}

비정적 중첩 클래스 예제

class OuterClass {
    class InnerClass {
        void display() {
            System.out.println("비정적 중첩 클래스");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        // 비정적 중첩 클래스는 외부 클래스의 인스턴스가 필요
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.display(); // 비정적 중첩 클래스
    }
}

지역 중첩 클래스 예제

class OuterClass {
    void outerMethod() {
        // 메서드 내부에 클래스 정의
        class LocalInnerClass {
            void display() {
                System.out.println("지역 중첩 클래스");
            }
        }

        // 지역 중첩 클래스의 객체 생성
        LocalInnerClass local = new LocalInnerClass();
        local.display();
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass outer = new OuterClass();
        outer.outerMethod(); // 지역 중첩 클래스
    }
}

익명 중첩 클래스 예제

interface Greeting {
    void sayHello();
}

public class Main {
    public static void main(String[] args) {
        // 익명 중첩 클래스
        Greeting greeting = new Greeting() {
            @Override
            public void sayHello() {
                System.out.println("익명 중첩 클래스");
            }
        };

        greeting.sayHello(); // 익명 중첩 클래스
    }
}

중첩 클래스의 장점

  1. 코드 그룹화:
    • 특정 클래스가 다른 클래스와 강하게 연관될 때, 해당 클래스를 논리적으로 그룹화 가능.
  2. 캡슐화 강화:
    • 외부 클래스와 관련된 클래스에 접근 범위를 제한하여 구현 세부 사항을 숨길 수 있음.
  3. 가독성 향상:
    • 중첩 클래스를 사용하면 외부 클래스와 강한 관계를 명확히 표현 가능.
  4. 외부 클래스 멤버에 접근 용이:
    • 비정적 중첩 클래스는 외부 클래스의 멤버에 쉽게 접근할 수 있음.

중첩 클래스의 단점

  1. 복잡성 증가:
    • 중첩 클래스 사용이 많아지면 코드가 복잡해질 수 있음.
  2. 메모리 누수 위험:
    • 비정적 중첩 클래스는 외부 클래스의 인스턴스를 암시적으로 참조하므로 메모리 누수가 발생할 가능성이 있음.

정리

  • 정적 중첩 클래스: 외부 클래스와 독립적으로 동작.
  • 비정적 중첩 클래스: 외부 클래스의 인스턴스와 밀접하게 연결.
  • 지역 중첩 클래스: 특정 메서드 내에서만 사용.
  • 익명 중첩 클래스: 1회성 구현에 적합.

중첩 클래스는 적절히 사용하면 코드의 논리적 그룹화를 돕고, 재사용성과 가독성을 높일 수 있는 강력한 도구입니다. 😊

LIST