-
[Java-25] 클래스 & 내부클래스 & 익명클래스Java 2020. 12. 9. 12:02
Java Class
🐵 Java 클래스
🙈 클래스?
어떤 객체지향 언어에서든지, 클래스라는 개념을 한번쯤은 들어봤을 것이다. 먼저 간단한 코드를 분석해보자,
- 자바에서 클래스를 선언
public class App { }
정말 쉽다, 이런식으로 public + class + name 다음과 같이 만들면 클래스 하나가 생성된 거다.
이제 클래스를 직접 만들어보면 애완동물 클래스인 Pet을 만들고, 여기에 변수도 넣어보자public class Pet { String kind; // 펫의 종류 String name; // 펫 이름 Integer age; // 펫 나이 }
이렇게 만들어 놓은 클래스는 우리가 마음대로 찍어낼 수 있다, 내가 강아지를 키우고 있다면 클래스를 변수로 선언하여, 클래스에다가 마음대로 집어넣을 수 있다. 마치 C의 구조체와 같이 말이다.
public static void main(String[] args) { Pet pet = new Pet(); pet.age = 10; pet.kind = "dog"; pet.name = "복실이"; System.out.println(pet.toString()); }
toString : 객체가 가진 정보를 String 으로 만들어 주는 함수 @Overriding 해야함
이 Pet 클래스를 선언함으로 써, 유저가 원하는 다양한 객체를 클래스를 통해서 선언이 가능해진다.
우리는 이 과정을 인스턴스 화 라고 한다.결과 콘솔
> Pet{kind='dog', name='복실이', age=-10}
🙉 이런 클래스를 가진 OOP 의 특징이 있다.
무결성, 은닉성, 캡슐화
- 이들의 특징과 장점은 나중에 알아보도록 하고, 이런게 있구나하고 넘어가도록 하자, Getter를 왜 사용하는지
- Setter를 왜 사용하는지, 그리고 class안에 method를 정의하면서 어떻게 활용이 가능한지 알 수 있다.
🙉 객체 생성부터 변수 생성까지
Class 는 이미 생성된 상황에서, 원하는 클래스에 Data 를 타입에 맞게 넣어놓고 객체를 생성할 수 있다. 책에서는 이 과정을 인스턴스 화 한다고 얘기한다.
이렇게 저장된 데이터는 JVM 메모리 영역의 Heap 에 올라가게 된다.
🐵 내부 클래스 (Inner Class)
🙈 내부 클래스?
내부 클래스는 말 그대로 클래스 안에 클래스가 있다는 소리다. 한가지 예를 들어보자
Java 로 구현한 Stack 코드 using Nodepublic class ListNodeStack { // 일반적인 클래스, 외부 클래스 Node topNode; // 내부클래스 Node 객체를 생성 @Getter class Node{ // 내부 클래스 int data; Node next; public Node (int data){ this.data = data; } } }
ListNodeStack 이라는 클래스 안에서, Stack 을 구현하기 위한 Node를 내부 클래스로 선언을 했다. 즉, 내부클래스는 일반적으로, 상위 클래스와 밀접환 연관이 있을 때 사용한다.
캡슐화
public class Computer{ Cpu cpu; Memmory memory; class Cpu{ String company; Integer price; String model; Double hz; } class Memory{ String company; Integer memorySize; String model; } ... }
- 이렇게 서로 연관되어있는 클래스를 이너클래스로 구현하여, 캡슐화의 근간이 된다.
🐵 익명 클래스
일반적인 클래스 사용법 public class Pet{ String name = "돼지"; public String getName(){ return name; } } public static main(String args[]){ Pet pet = new Pet(); // 인스턴스 선언 }
🙈 익명 클래스
- 이번에는 익명클래스에 대해서 알아보는 시간을 가져보도록 하자
- 익멸 클래스는 이름이 지정되어 있지 않은 클래스를 의미한다.
정확히 익명클래스를 선언하는 방법에는 2가지가 있다.
🙉 익명클래스를 사용하는 방법
1. Interface를 implemets 를 받아 사용한다.
2. Class를 상속 받아서 사용한다.
1. 인터페이스 implements 사용법
public interface Monster{ String getName(); } public static void main(String args[]){ Monster monster = new Monster(){ String name; public String getName(){ return name; } }; System.out.println(monster.getName()); }
이 형식 어디서 많이 보지 않았는가? 만약 쓰레드를 공부했다면 Runnable 과 같은 형태라는 걸 눈치채챌 수 있다. 나중에 설명하겠지만 Runnable, Thread 선언 하는 이 두가지 방법도 비슷한 방식이라고 생각 하면된다. Thread는 조만간 다뤄보도록 하자 : D
2.익명 클래스 상속 사용법
public class Pet{ String name = "돼지"; public String getName(){ return name; } } public static void main(String[] args){ Pet pet = new Pet(){ String name = "익명 돼지"; @Override public String getName(){ return name; } }; System.out.println(pet.getName()); // 결과 : 익명 돼지 }
이렇게 클래스를 직접 상속 받아서, getName() 을 오버라이딩 해서 사용하는 방법이 있다. 그러면 이런 생각을 할 수 있다. "야 지금 이거 상속이고 뭐고, 그냥 pet 클래스 아니야?" 일단 이 질문에는 아니다. 언뜻보면, 그냥 Pet 클래스를 선언에서 오버라이드 좀 한걸로 볼 수 있지만 그렇지 않다.
🙉 Pet 익명클래스는 Pet 클래스가 아니다. 간단한 확인
🙈 생성된 인스턴스의 클래스 이름 확인 'instance.getClass().getName'
public static void main(String[] args) { Pet pet = new Pet(); Pet pet2 = new Pet(); System.out.println(pet.getClass().getName()); // 결과 Pet System.out.println(pet2.getClass().getName()); // 결과 Pet }
- 이 클래스들 pet 과 pet2는 일반적인 방법으로 객체를 생성한 것이다. 그럼 이 클래스의 이름은 뭐라고 뜰까?
🙈 생성된 인스턴스의 클래스 이름 확인 'instance.getClass().getName'
public static void main(String[] args) { Pet pet = new Pet(){ //익명 클래스 1개 선언 //@Override }; Pet pet2 = new Pet(){ //익명 클래스 2개 선언 //@Override }; System.out.println(pet.getClass().getName()); // 결과 Pet$1 System.out.println(pet2.getClass().getName()); // 결과 Pet$2 }
결과 값이 신기하지 않은가? Pet + $ + n(생성된 몇번 째) 이런식의 클래스 이름이 나온다. 그러니깐 결론은, 자바에서는 이 서로 두개의 클래스를 같은 클래스로 보고 있지 않다는 것이다.
🙈 인터페이스로 선언된 익명 클래스는 현재 main에 속해있는 클래스 이름을 반환
public interface Monster { String getName(); } public static void main(String[] args) { Monster mon = new Monster(){ //익명 클래스 1개 선언 //@Override }; Moster mon2 = new Moster(){ //익명 클래스 2개 선언 //@Override }; System.out.println(mon.getClass().getName()); // 결과 Pet$1 System.out.println(mon2.getClass().getName()); // 결과 Pet$2 }
현재 클래스로 구현되어있기 때문에 지금 속해있는 main 클래스의 클래스 명을 반환한다.
'Java' 카테고리의 다른 글
[Java-27] 자바 생성자에 대한 고찰 (0) 2020.12.18 [Java-26] 자바 new & Heap, Constant pool (1) 2020.12.14 [Java-24] junit 추가하는법, 간단 사용법 (0) 2020.12.04 [Java-23] 자바 조건문, 반복문 (0) 2020.12.04 [Java-22] 자바13 스위치, java13 switch 연산 (0) 2020.11.27