[F-lab 모각코 챌린지 26일차] TIL

JeongheeKim·2023년 6월 26일

TIL

목록 보기
26/66

학습계획


  • 중첩클래스 사용 이유
  • 익명객체
  • 인터페이스 익명 구현 객체

Today I Learned


중첩클래스 사용 이유

  • 하나의 클래스에서만 사용될 경우 논리적으로 묶기 위해 중첩클래스로 선언한다.

  • 캡슐화 증가

    • 내부 클래스로 선언하면서 감싸는 클래스의 private 변수를 공개할 필요 없어 캡슐화를 증대시킬 수 있다.
  • 코드 가독성 증가

    • 중첩클래스가 하나의 코드파일안에 존재하므로 가독성이 좋아진다.
  • 정적 클래스메소드와 마찬가지로 staic 중첩 클래스는 해당 클래스에 정의된 필드, 메소드를 직접 접근 할 수 없다.

public class OuterClass {
	String outerField = "Outer field";
	static String staticOuterField = "Static Outer field";

	class InnerClass {
		void accessMembers() {
			System.out.println("outerField = " + outerField);
			System.out.println("staticOuterField = " + staticOuterField);
		}
	}

	static class StaticNestedClass {
		void accessMembers(OuterClass outer) {
			//System.out.println(outerField);//접근 불가
			System.out.println(outer.outerField);
			System.out.println(staticOuterField);
		}
	}

	public static void main(String[] args) {
		System.out.println("Inner class:");
		System.out.println("------------");
		OuterClass outerClass = new OuterClass();
		OuterClass.InnerClass innerClass = outerClass.new InnerClass();
		innerClass.accessMembers();

		System.out.println("\nStatic nested class:");
		System.out.println("--------------------");
		StaticNestedClass staticNestedClass = new StaticNestedClass();
		staticNestedClass.accessMembers(outerClass);

		System.out.println("\nTop-level class:");
		System.out.println("--------------------");
		TopLevelClass topLevelClass = new TopLevelClass();
		topLevelClass.accessMember(outerClass);
	}
}
public class TopLevelClass {
	void accessMember(OuterClass outer) {
		//System.out.println(OuterClass.outerField);
		System.out.println(outer.outerField);
		System.out.println(OuterClass.staticOuterField);
	}
}

익명객체

→ 익명 객체를 공부하다보면 람다식이 같이 나오는데 람다식의 내용은 다음번에

  • 객체의 이름이 없으며, 명시적으로 클래스를 선언하지 않아 쉽게 객체 생성이 가능하다.
  • 익명객체는 주로 필드값, 로컬 변수값, 매개변수값으로 주로 사용됨
  • 익명객체는 클래스를 상속하거나 인터페이스를 구현해야만 생성할 수 있다.
  • 익명객체 중괄호 블럭
    new 부모생성자(매개값,...) {
    	
    }
    • 익명객체가 가져야할 멤버필드, 메소드위치
    • 익명 자식객체는 부모타입에 대입되므로 부모타입에 선언된 멤버만 접근 할 수 있다.
    • 중괄호 블럭 안에는 주로 부모 메소드를 재정의하는 코드가온다.
  • 선언과 동시에 인스턴스화가 된다.
  • 로컬 클래스와 이름이 없다는 점 빼고 동일하며 로컬클래스를 한번만 사용한다면 익명클래스를 사용하라.
    • 일회용이기때문에 클래스를 작성하는것이 비효율적이기 때문에, 익명 클래스를 통해 코드를 줄이는(클래스를 상속하지 않고, 익명의 inline으로 해결) 일종의 기법
  • 부모클래스의 상속을 일회성으로 재정의한것이기 때문에 익명 클래스에서 새롭게 정의된 메서드는 익명클래스 밖에서 호출이 안된다.

인터페이스 익명 구현 객체

  • 익명 클래스 구현보다는 인터페이스를 익명 객체로 구현하는 방식이 실무에서 더 자주 사용하게 된다.
  • 상속과 다르게 인터페이스는 강제적으로 구현되야 하므로 규격화에 도움이 된다.
  • 단, 하나의 인터페이스를 통한 구현만 가능하다.
    interface Animal {
    	String bark();
    
    	String run();
    }
    
    public class Main {
    	public static void main(String[] args) {
    		Animal dog = new Animal() {
    			@Override
    			public String bark() {
    				return "왈왈왈";
    			}
    
    			@Override
    			public String run() {
    				return "달린다 왈왈";
    			}
    		};
    		System.out.println(dog.bark());
    		System.out.println(dog.run());
    	}
    }
  • 인터페이스 익명 구현 객체는 메소드의 argument로 일회성객체를 넘겨주는 방식으로 자주 사용된다.
    public class Main {
    	public static void main(String[] args) {
    		class User {
    			String name;
    			int age;
    
    			public User(String name, int age) {
    				this.name = name;
    				this.age = age;
    			}
    		}
    		User[] users = {
    			new User("홍길동", 32),
    			new User("김춘추", 64),
    			new User("임꺽정", 48),
    			new User("박혁거세", 14)
    		};
    		Arrays.sort(users, new Comparator<User>() {
    			@Override
    			public int compare(User o1, User o2) {
    				return Integer.compare(o1.age, o2.age);
    			}
    		});
    	}
    }

[참고]


https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

https://inpa.tistory.com/entry/JAVA-☕-익명-클래스Anonymous-Class-사용법-마스터하기

0개의 댓글