본문 바로가기

JAVA

다른 형식의 클래스 & Marker interface

반응형
SMALL
내부 클래스(Inner Class)

내부클래스 : 클래스 내부에 선언된 클래스
외부클래스 : 내부클래스를 가진 클래스

 

내부 클래스로 선언된 클래스는 외부클래스를 상속받지 않아도 외부 클래스의 멤버들을
사용할 수 있다. 외부 클래스가 메모리에 할당되어야 내부 클래스의 객체화가 가능하므로
내부클래스만 별도로 사용하지 못한다.

 

어느 위치에 선언하느냐에 따라서 4가지 형태가 있을 수 있다.

 

  • 첫번째는 클래스 안에 인스턴스 변수, 즉 필드를 선언하는 위치에 선언되는 경우로 보통 중첩클래스 혹은 인스턴스 클래스라고 한다.
	public class InnerExam1{
		class Cal{
			int value = 0;
			public void plus(){
				value++;
			}
		}
	
		public static void main(String args[]){
			InnerExam1 t = new InnerExam1();
 // 내부에 있는 Cal객체를 생성하기 위해서는,
 // 밖에는 InnerExam1의 객체를 만든 후에 InnerExam1.Cal cal = t.new Cal();과 같은 방법으로 Cal객체를 생성한 후 사용한다.
			InnerExam1.Cal cal = t.new Cal();
			cal.plus();
			System.out.println(cal.value);
	
		}
	}

 

  • 두번째는 내부 클래스가 static으로 정의된 경우, 정적 중첩 클래스 또는 static 클래스라고 한다.
	public class InnerExam2{
		static class Cal{
			int value = 0;
			public void plus(){
				value++;
			}
		}
	
		public static void main(String args[]){
// 필드 선언할 때 스태틱한 필드로 선언한 것과 같다.
// 이 경우에는 InnerExam2객체를 생성할 필요없이 new InnerExam2.Cal() 로 객체를 생성할 수 있다.
			InnerExam2.Cal cal = new InnerExam2.Cal();
			cal.plus();
			System.out.println(cal.value);
	
		}
	}

 

  • 세번째로는 메소드 안에 클래스를 선언한 경우, 지역 중첩 클래스 또는 지역 클래스라고 한다.
	public class InnerExam3{
		public void exec(){
			class Cal{ // 메소드 안에서 해당 클래스를 이용할 수 있다.
				int value = 0;
				public void plus(){
					value++;
				}
			}
			Cal cal = new Cal();
			cal.plus();
			System.out.println(cal.value);
		}
		
	
		public static void main(String args[]){
			InnerExam3 t = new InnerExam3();
			t.exec();
		}
	}

 

익명 클래스(Anonymous Inner Class)

생성자 다음에 중괄호 열고 닫고가 나오면,

해당 생성자 이름에 해당하는 클래스를 상속받는 이름없는 객체를 만든다는 것을 뜻하며,

이름이 있다는 것은 재사용을 하겠다.

이름이 없다는 것은 재사용을 하지 않겠다.

 

따라서 이름이 없는 클래스는 일회성으로 이름이 없어서 불러올 수 없기 때문에 재사용할 수 없다.

미구현된 멤버를 구현하여 일회용으로 객체를 생성하기위해 사용한다.

 

  • 네번째로는 익명 중첩 클래스는 익명 클래스라고 보통 말하며, 내부클래스이기도 하다.

자료형인 ClassA

public class ClassA {

	void printData() {

	}
}

 

추상클래스

public abstract class AbstractA {
	abstract void printData();
}

 

인터페이스

public interface InterA {
	void printData();
}

 

익명클래스

public class AnonymousTest {

	public static void main(String[] args) {

		// 익명클래스
		// 오버라이딩은 클래스 안에서 선언이 가능하기 때문에 내부클래스에서 선언할 수 있다.
		
		ClassA classA2 = new ClassA();
		classA2.printData(); // 부모의 주소값을 가져오기 때문에 빈 값이다.
		
		
		// 자료형인 ClassA인 classA 변수에
		// 익명 클래스의 객체의 주소값을 담는다.
		ClassA classA = new ClassA() {
			@Override
			void printData() {
				System.out.println("data");
			}
		};
		// 익명클래스로 찍어낸 객체의 주소값으로 출력된다.
		classA.printData();

		
		// 추상클래스를 통한 익명 클래스 객체화
		AbstractA abstractA = new AbstractA() {
			@Override
			void printData() {
				System.out.println("abstract class");
			}
		};
		abstractA.printData();

		
		// 인터페이스를 통한 익명 클래스 객체화
		InterA interA = new InterA() {
			@Override
			public void printData() {
				System.out.println("interface");

			}
		};
		interA.printData();
	}

}

 

마커 인터페이스(Marker interface)

클래스들을 그룹화하기 위한 목적으로 사용한다.
인터페이스는 지정한 클래스의 부모이며, 모든 자식은 부모의 타입을 가지고 있으므로
마커 인터페이스를 지정받은 클래스들이 하나의 타입으로 묶이게 된다.

 

public class Animal {
	
}

 

BirdsMarker

public interface BirdsMarker {

}
public class Eagle extends Animal implements BirdsMarker {

}
public class Pigeon extends Animal implements BirdsMarker {

}

 

MammalMarker

public interface MammalMarker {
	
}
public class Cat extends Animal implements MammalMarker{
	
}
public class Dog extends Animal implements MammalMarker{

}

 

Animal의 주소값을 가지고 온다.

public class MarkerTest {

	public static void main(String[] args) {

		// 메소드의 매개변수로 Animal을 전달받는데 해당 동물이 네발 동물이면 네발로 걸어간다.
		// 메소드의 매개변수로 Animal을 전달받는데 해당 동물이 날개가 있다면 날아간다.

		// 실습1 checkAnimal 메소드를 완성시키기
		// 조건1. 매개변수로 모든 동물을 받을 수 있어야 한다.
		// 조건2. 만약 지금 매개변수로 전달된 동물이 조류라면 "날아갑니다." 라고 출력
		// 조건3. 만약 지금 매개변수로 전달된 동물이 포유류라면 "네발로 걸어간다." 라고 출력
		
		// 매개변수로 어떤 타입을 받을 것인가? 형변환
		// 지금 해당 변수가 어떤 타입인지 어떻게 확인할 것인가? instanceof
		
		
		Dog dog = new Dog();
		Cat cat = new Cat();
		Eagle eagle = new Eagle();
		Pigeon piegeon = new Pigeon();
		
		MarkerTest.checkAnimal(dog); // Animal animal = dog; 와 같은 내용이다.
//		MarkerTest.checkAnimal(new Dog()); // 위 코드와 같은 내용이다.
		MarkerTest.checkAnimal(cat);
		MarkerTest.checkAnimal(eagle);
		MarkerTest.checkAnimal(piegeon);
	}


	// Animal animal = new Dog(); // UpCasting 상태이다.
	static void checkAnimal(Animal animal) { // Animal의 주소값을 가지고 온다.
		if(animal instanceof MammalMarker) {
			System.out.println("네발로 걸어간다."); // dog, cat 해당
		}else if(animal instanceof BirdsMarker) {
			System.out.println("날아갑니다."); // eagle, piegeon 해당
		}
		
	}
}
반응형
LIST

'JAVA' 카테고리의 다른 글

Object 클래스, Wrapper 클래스, StringBuffer 클래스, Math 클래스  (2) 2022.11.29
람다식(Lambda Expression) & 예외처리(Exception)  (0) 2022.11.22
인터페이스(Interface)  (0) 2022.11.16
상속(Inheritance)  (0) 2022.11.10
클래스  (0) 2022.11.06