티스토리 뷰

728x90
반응형

오늘은 저번 게시물에 이어 추상클래스에 대해 더욱 알아보려 한다. 저번 게시물은 아래 링크에!! 

 

https://live-for-myself.tistory.com/94

 

[Java] 추상 클래스 Abstract Class #1

자바에는 "추상 클래스"라는 것이 존재한다. 미완성된 메소드를 하나 이상 포함하는 클래스를 추상 클래스라 하는데, 이때 미완성된 클래스를 "추상 메소드" 라고 한다. 추상 클래스의 특징에는

live-for-myself.tistory.com


1. "내부 클래스 inner class"

 

Zoo.java - Zoo 클래스 안의 내부 클래스 Monkey와 Tiger

package test.mypac;

public class Zoo {
	//메소드
	public Monkey getMonkey() {
		return new Monkey();
	}
	
	public Tiger getTiger() {
		return new Tiger();
	}
	
	//클래스 안에 클래스 (내부 클래스, inner class)
	public class Monkey{
		public void say() {
			System.out.println("안녕! 나는 원숭이야");
		}
		
	}
	
	public class Tiger{
		public void say() {
			System.out.println("어흥! 나는 호랑이다!");
		}
		
	}

}

클래스 안에 클래스를 정의할 수 있다. 이를 inner class라고 한다. 

Zoo클래스는 두개의 메소드와 두개의 내부클래스를 가진다.

Zoo클래스를 main에서 활용해보자.


우선 Zoo 객체를 생성하여 Zoo타입의 변수 z에 참조값을 넣어보자.

Zoo z = new Zoo();

 

z의 getMonkey()와 getTiger() 메소드를 호출해보자.

getMonkey()의 반환 타입은 Monkey형이므로 Monkey 타입의 지역변수에 참조값을 저장할 수 있다.

getTiger() 역시 마찬 가지로, 반환 타입이 Tiger형이므로 Tiger 타입의 지역변수에 참조값을 저장할 수 있다.

Monkey m1 = z.getMonkey();
Tiger t1 = z.getTiger();

 

이제 m1과 t1은 Zoo의 inner class 인 Monkey와 Tiger타입이다.

따라서, m1과 t1의 say()메소드를 각각 호출하면 다음과 같은 출력이 나온다.

m1.say();
t1.say();

 

 

출력 결과


2. " 메소드 안의 클래스 local inner class"

 

클래스 안에 만든 클래스를 inner class라 했다. 

메소드 안에도 클래스를 만들 수 있는데 이를 local inner class 라고 한다.

메소드 안에 메소드는 만들 수 없다.

 

예제를 통해 살펴보자.


MainClass04.java - main 메소드 안에 클래스 생성하기 

package test.main;

/*
 * 클래스 안에 만든 클래스 : inner class
 * 메소드 안에 만든 클래스 : local inner class
 * 메소드 안에 메소드 : 생성 불가
 */
public class MainClass04 {
	
	public static void main(String[] args) {
		//메소드 안에도 클래스를 정의할 수 있다.
		//local inner class
		class Gura{
			public void say() {
				System.out.println("안녕 나는 구라야!");
			}
			
		}
		
		Gura g = new Gura();
		g.say();
	}

}

메인 메소드 안에 Gura클래스를 생성하였다.

Gura클래스는 say() 메소드를 가진다.

Gura 객체를 생성하여 Gura 타입 지역변수 g에 담고, g.say()를 통해 local inner class의 메소드를 호출할 수 있다.


문제

MainClass05의 useWeapon() 메소드를 호출하는 게 목적이다.

호출하려고 보니 Weapon 추상클래스 type 객체의 참조값이 필요하다.

클래스를 따로 파일로 만들기 귀찮은데 다른 방법이 없을까? 

inner Class로와 local inner Class를 활용하여 호출해보자.


MainClass05.java

package test.main;

import test.mypac.Weapon;

public class MainClass05 {
   public static void main(String[] args) { 
	
   }
   //static 메소드는 static 영역에 올라가므로 static 예약어를 붙여줘야 쓸 수 있다.
   public static void useWeapon(Weapon w) {
	   w.prepare();
	   w.attack();
   }
}

Solution

 

1. inner class YourWeapon을 만들어보자.

package test.main;

import test.mypac.Weapon;

public class MainClass05 {
	//static 메소드에서 사용하기 위해 static 예약어가 필요하다. 
	static class YourWeapon extends Weapon{

		@Override
		public void attack() {
			System.out.println("아무거나 공격해요");
		}
	}
	
   public static void main(String[] args) { 
   
   	   useWeapon(new YourWeapon());
	 
   }
   //static 메소드는 static 영역에 올라가므로 static 예약어를 붙여줘야 쓸 수 있다.
   public static void useWeapon(Weapon w) {
	   w.prepare();
	   w.attack();
   }
}

main에서 호출할 건데, main은 static 영역에 있다. 

main에서 YourWeapon을 사용하려면 YourWeapon도 static 영역에 있어야 한다.

따라서, YourWeapon에 static을 붙여준다.

 

 

2. local inner class OurWeapon을 만들어보자.

package test.main;

import test.mypac.Weapon;

public class MainClass05 {
	
   public static void main(String[] args) {
	 
	 //local inner class로도 만들어보자.
	 class OurWeapon extends Weapon{

		@Override
		public void attack() {
			System.out.println("공격! 공격!");
		} 
	 }
	 useWeapon(new OurWeapon());
   }
   //static 메소드는 static 영역에 올라가므로 static 예약어를 붙여줘야 쓸 수 있다.
   public static void useWeapon(Weapon w) {
	   w.prepare();
	   w.attack();
   }
}

 

 

전체 코드

MainClass05.java

package test.main;

import test.mypac.Weapon;

public class MainClass05 {
	//static 메소드에서 사용하기 위해 static 예약어가 필요하다. 
	static class YourWeapon extends Weapon{

		@Override
		public void attack() {
			System.out.println("아무거나 공격해요");
		}
	}
	
   public static void main(String[] args) { 
	/*
	 * useWeapon() 메소드를 호출하는 게 목적이다.
	 * 호출하려고 보니 Weapon 추상클래스 type 객체의 참조값이 필요하다.
	 * 클래스를 따로 파일로 만들기가 귀찮다.
	 * 그렇다면 어떻게 해야할까?
	 * 
	 * 내부 클래스(inner class)로 만들어보자.
	 */
	 useWeapon(new YourWeapon());
	 
	 
	 //local inner class로도 만들어보자.
	 class OurWeapon extends Weapon{

		@Override
		public void attack() {
			System.out.println("공격! 공격!");
			
		}
		 
	 }
	 
	 useWeapon(new OurWeapon());
	 
   }
   //static 메소드는 static 영역에 올라가므로 static 예약어를 붙여줘야 쓸 수 있다.
   public static void useWeapon(Weapon w) {
	   w.prepare();
	   w.attack();
   }
}

3. "익명의 local inner 클래스" 

 

외부 클래스, 내부 클래스, 로컬 내부 클래스 생성으로 추상클래스를 사용할 수 있었다.

이번에는 익명 클래스를 사용해보려 한다. 

 

익명 클래스는 다음과 같이 생겼다.

Weapon w1 = new Weapon() {//중괄호부터 이름이 없는 익명의 클래스. new Weapon()은 익명의 클래스의 생성자를 호출한다.
		   @Override
		   public void attack() {
			   System.out.println("아무나 공격해요!");		
		   }
	   };
	
	   useWeapon(w1);

 

new Weopon() 뒤의 중괄호부터가 바로 이름이 없는 익명의 클래스이다.

new Weapon() 익명 클래스의 생성자를 호출한다.

 

위에서는 w1에 생성한 익명 클래스의 참조값을 담아주었지만, useWeapon안에 바로 사용할 수도 있다.

useWeapon(new Weapon() {
		
		@Override
		public void attack() {
			System.out.println(("공중 공격을 해요"));
			
		}
	});

 

 

전체 코드

MainClass06.java

package test.main;

import test.mypac.Weapon;

public class MainClass06 {
   public static void main(String[] args) {
	   //익명의 lcoal inner class를 이용해서 Weapon type 참조값 얻어내기
	   Weapon w1 = new Weapon() {//중괄호부터 이름이 없는 익명의 클래스. new Weapon()은 익명의 클래스의 생성자를 호출한다.
		   @Override
		   public void attack() {
			   System.out.println("아무나 공격해요!");		
		   }
	   };
	
	   useWeapon(w1);
	   
	   useWeapon(new Weapon() {
		
		@Override
		public void attack() {
			System.out.println(("공중 공격을 해요"));
			
		}
	});
      
     
   }
   
   public static void useWeapon(Weapon w) {
	   w.prepare();
	   w.attack();
   }
}

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함