웹_프론트_백엔드/단과

[단과_JAVA_심화반] 2020.08.25

shine94 2020. 8. 25. 23:55

1. Marker Interface
 : 클래스들의 공통 그룹명으로 인터페이스를 생성하고 아무것도 구현해놓지 않는다.
   즉, 그 클래스들이 같은 그룹으로 묶였다는 표시를 하기 위해 사용한다.

 

[추가] 위의 예시와 같이 Marker Interface로 묶게되면 instanceof 건설을 통해 모든 건설 타입을 확인할 수 있다.

 

2. Marker Interface 예시

 : 샌드박스에는 많은 비디오 영상이 있다.
   현재...!

   샌드박스에 들어있는 모든 비디오 영상은 이미 Video를 상속받은 상태이다.
   그러나...!

   나는 많은 비디오 영상 중 애니메이션만 추출하고 싶다.
   가능할까? 만약 가능하다면 어떻게 해야하나?

   이럴때는 마커 인터페이스를 이용하면 된다(애니메이션이라는 공통분모를 마커 인터페이스를 통해 묶기).

 

[샌드박스에는 많은 영상들이 있다]

** com.lec.java.markerInterface > Video.java

package com.lec.java.markerInterface;

// 샌드박스에는 많은 비디오 영상들이 있다.
public class Video {

}

 

[나는 많은 비디오 영상 중 애니메이션만 추출하고 싶다 / but 이미 Video를 상속받은 상태]

** com.lec.java.markerInterface > Ddolbee.java : 애니메이션

package com.lec.java.markerInterface;

public class Ddolbee extends Video implements Animation {

}

 

** com.lec.java.markerInterface > Bbororo.java : 애니메이션

package com.lec.java.markerInterface;

public class Bbororo extends Video implements Animation {

}

 

** com.lec.java.markerInterface > RunHanee.java : 애니메이션

package com.lec.java.markerInterface;

public class RunHanee extends Video implements Animation {

}

 

** com.lec.java.markerInterface > Titanic.java : 영화

package com.lec.java.markerInterface;

public class Titanic extends Video{

}

 

[애니메이션이라는 공통분모를 묶기 위해 마커 인터페이스를 만듦]

** com.lec.java.markerInterface > 인터페이스 Animation

package com.lec.java.markerInterface;

// 마커 인터페이스
// 애니메이션임을 구분하기 위해 만듦
public interface Animation {;}

 

[마커 인터페이스와 instanceof 연산자를 이용, 애니메이션인지 검사하는 메소드를 만들었다!]

** com.lec.java.markerInterface > TV.java

package com.lec.java.markerInterface;

// 많은 비디오 영상들 중에 애니메이션만 추출하고 싶다.
// 마커 인터페이스를 이용
// 애니메이션인지 아닌지 판단하는 메소드 만듦
public class TV {
	
	//외부에서 전달받은 영상 목록 중 애니메이션인지 아닌지 판단하는 메소드
	public void checkAni(Video[] arVideo) {
		for (int i = 0; i < arVideo.length; i++) {
			if(arVideo[i] instanceof Animation) {
				System.out.println("애니메이션 입니다.");
			}else {
				System.out.println("애니메이션이 아닙니다.");
			}
		}
	} // end checkAni()
	
	public static void main(String[] args) {
		
		Video[] arVideo = {
				new Ddolbee(),	// Up-Casting
				new Bbororo(),	// Up-Casting
				new RunHanee(),	// Up-Casting	
				new Titanic()	// Up-Casting
		};
		
		new TV().checkAni(arVideo);
		
	} // end main()
	
} // end class

 

 

3. 내부 클래스(inner class)
 : 클래스 내부에 클래스를 선언하여 외부 클래스의 필드 접근에 용이하기 위함.
   내부 클래스의 필드를 사용하기 위해서는 외부 클래스에서 내부클래스를 객체화 해야한다.

 

   외부클래스명 외부객체명 = new 외부생성자();
   외부클래스명.내부클래스명 내부객체명 = 외부객체명.new 내부생성자();

 

 

4. 캡슐화
 : A 클래스에서 a뿐만 아니라 b라는 작업이 자주 쓰이고, 이 작업은 B 클래스를 만들어야 쉽게 관리할 수 있다.
   하지만 다른 클래스에서 b작업이 필요 없거나 B클래스를 "외부에 노출시키고 싶지 않을 때 사용하는 기법"이다.

※ 내부 클래스는 GUI, 안드로이드 어플 개발시 많이 사용된다.

 

 

5. 내부클래스 사용 예시

 : 예를 들어 주문이 들어오면 배달이 되는 프로세스를 만든다고 하자!

   원래의 내부 클래스를 사용하지 않는 방식...!

   주문class와 주문class를 상속받은 배달class를 따로 만들어줘야하는 번거로움(+ 코드 복잡함)이 있다.

   그러나 내부클래스 이용하면...!

   주문class 안에 배달inner class를 만들고

   배달inner class 안에 주문과 배달을 편하게 만들 수 있다(+ 캡슐화의 장점은 덤으로 얻어갈 수 있음).

 

 

6. 내부클래스 코드 예시

** com.lec.java.innerClass > InnerTest.java

package com.lec.java.innerClass;

class Out {
	int outData;
	
	public Out() {
		System.out.println("외부 클래스 생성자 호출됨.");
	}
	
	public void intro_out() {
		System.out.println("외부 클래스 메소드 호출됨.");
	}
	
	// 내부클래스, 캡슐화
	// 내부클래스는 외부클래스의 같은 필드 안에만 있을 뿐 자식이 아니다.
	// 자식은 반드시 extends로 받는다는 점 꼭 기억하기!
	class In {
		int inData;
		
		public In() {
			System.out.println("내부 클래스 생성자 호출됨.");
		}
		
		public void intro_in() {
			outData = 100;
			System.out.println(outData);
			intro_out();
			System.out.println("내부 클래스 메소드 호출됨.");
		}
		
	} // end In class
	
} // end Out class

public class InnerTest {
	
	public static void main(String[] args) {
		Out out = new Out();
		
		// 일단 외부클래스가 인스턴스 되어야 내부 클래스도 인스턴스 된다..!!
		Out.In in = out.new In();
		
		in.intro_in();
		
	} // end main()

} // end InnerTest class

 


7. 익명클래스(Anonymous inner class)
 : 이름이 없는 클래스(일회성으로 사용하기 위함)

 

 

8. 익명클래스 예시

** com.lec.java.anonymous > 인터페이스 Cafe

package com.lec.java.anonymous;

public interface Cafe {
	String[] getMenu();
	void sell(String choice);
}

 

** com.lec.java.anonymous > Starbucks.java

package com.lec.java.anonymous;

public class Starbucks {
	
	String[] menus;
	
	void regist(Cafe c) {
		menus = c.getMenu();
		
		System.out.println("------------축 개업------------");
		for (int i = 0; i < menus.length; i++) {
			System.out.println(menus[i]);
		}
		
		c.sell("아메리카노");
		
	} // end regist()

} // end class

 

** com.lec.java.anonymous > Road.java

package com.lec.java.anonymous;

public class Road {
	
	public static void main(String[] args) {
		
		Starbucks gangnam = new Starbucks();
		gangnam.regist(new Cafe() {
			
			@Override
			public void sell(String choice) {
				String[] arMenu = getMenu();
				for (int i = 0; i < arMenu.length; i++) {
					if(arMenu[i].equals(choice)) {
						System.out.println(choice + "구매 완료");
					}
				}
				
			}
			
			@Override
			public String[] getMenu() {
				String[] arMenu = {"아메리카노", "카페라떼", "수박주스"};
				return arMenu;
			}
		});
		
	} // end main()

} // end class

 

 

9. 익명클래스 문제
 : 나이키 매장은 본사에 등록할 때 판매물품목록과 판매 방식을 알려주어야 한다.
   만약 무료나눔 행사중인 매장은 판매 방식을 알려주지 않아도 된다.
   (추상클래스, 인터페이스, 내부클래스, 익명클래스, up casting을 사용해라)

 

[내 코드]
** com.lec.java.practice.me > 인터페이스 Market

package com.lec.java.practice.me;

public interface Market {
	String[] getMenu();
	void sell(String choice);
}

 

** com.lec.java.practice.me > 추상클래스 MarketAdapter

package com.lec.java.practice.me;

public abstract class MarketAdapter implements Market {

	@Override
	public abstract String[] getMenu();

	@Override
	public void sell(String choice) {}
	
}

 

** com.lec.java.practice.me > Nike.java

package com.lec.java.practice.me;

public class Nike {

	String[] menus;
	
	void regist(Market m) {
		menus = m.getMenu();
		
		System.out.println("------------축 개업------------");
		for(int i = 0; i < menus.length; i++) {
			System.out.println(menus[i]);
		}
		
		m.sell("운동화");
		
	} // end regist()

} // end class

 

** com.lec.java.practice.me > Road.java

package com.lec.java.practice.me;

public class Road {
	
	public static void main(String[] args) {
		// 강남점 매장 등록
		Nike gangnam = new Nike(); 
		gangnam.regist(new MarketAdapter(){
			
			@Override
			public String[] getMenu() {
				String[] arMenu = {"운동화", "슬리퍼", "센들"};
				
				return arMenu;
			}
			
			@Override
			public void sell(String choice) {
				String[] arMenu = getMenu();
				
				System.out.println("고객님이 구매한 상품----------------");
				for(int i = 0; i < arMenu.length; i++) {
					
					if(arMenu[i].equals(choice)) {
						System.out.println(choice + "구매 완료");
					}
				}
				
			};
			
		});
		
		// 무료 나눔 행사중인 매장
		Nike freeSharing = new Nike(); 
		freeSharing.regist(new MarketAdapter(){
			
			@Override
			public String[] getMenu() {
				String[] arMenu = {"운동화", "슬리퍼", "센들", "하이힐"};
				
				return arMenu;
			}
			
		});
		
	} // end main()

} // end class


[강사님 코드]

** com.lec.java.practice.teacher > 인터페이스 Market

package com.lec.java.practice.teacher;

public interface Market {
	String[] getMenu();
	void sell(String choice);
}

 

** com.lec.java.practice.teacher > 추상클래스 MarkerAdapter

package com.lec.java.practice.teacher;

public abstract class MarketAdapter implements Market{
	
	@Override
	public String[] getMenu() {return null;}
	
	@Override
	public void sell(String choice) {}
	
}

 

** com.lec.java.practice.teacher > Nike.java

package com.lec.java.practice.teacher;

public class Nike {
	String[] menus;
	
	void regist(Market m) {
		menus = m.getMenu();
		
		System.out.println("------------메뉴판-----------");
		for (int i = 0; i < menus.length; i++) {
			System.out.println(menus[i]);
		}
		
		if(!(m instanceof MarketAdapter)) {
			m.sell("축구공");
		}
	}
}

 

** com.lec.java.practice.teacher > Road.java

package com.lec.java.practice.teacher;

public class Road {
	
	public static void main(String[] args) {
		Nike gangnam = new Nike();
		Nike jamsil = new Nike();
		
		jamsil.regist(new MarketAdapter() {
			@Override
			public String[] getMenu() {
				String[] arMenu = {"운동화", "슬리퍼", "센들", "축구공"};
				
				return arMenu;
			}
		});
		
		gangnam.regist(new Market() {
			
			@Override
			public void sell(String choice) {
				String[] arMenu = getMenu();
				
				System.out.println("고객님이 구매한 상품----------------");
				for(int i = 0; i < arMenu.length; i++) {
					
					if(arMenu[i].equals(choice)) {
						System.out.println(choice + " 구매 완료");
					}
				}
			}
			
			@Override
			public String[] getMenu() {
				String[] arMenu = {"운동화", "슬리퍼", "센들", "축구공"};
				
				return arMenu;
			}
		});
		
	}
}

 

 

10. UI(User Interface) : 기계와 사람 사이의 작용 / UX(User Experience) : 사용자의 경험
   ex) 자동차를 만들려고 한다.

        UI는 헨들은 네모 모양은 안돼 동그란 모양만 만들 수 있고

        UX는 자동차는 헨들이 있기 때문에 헨들을 만들어야 한다.

 


11. GUI(Graphical User Interface)

   ① 컨테이너: 컴포넌트를 붙일수 있는 판떼기
   ② 컴포넌트: 컨테이너에 붙이는 거, ex) 버튼
   ③ 레이아웃: 컨테이너를 컴포넌트에 붙일때 어디에 위치할 것인지
   ④ 이벤트: 눌렀을 때 반응 내용


12. GUI 예시

** com.lec.java.gui > ButtonTest.java

package com.lec.java.gui;

import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ButtonTest extends Frame implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		switch(e.getActionCommand()) {
		case "1":
			System.out.println("첫번째");
			break;
		case "2":
			System.out.println("두번째");
			break;
		}
	}
	
	public ButtonTest() {
		super("버튼 테스트");				// title명, 제목표시줄에 "버튼 테스트" 이름 설정
		setBounds(580, 150, 500, 500);	// 뜰 창의 크기
		
		// 버튼 2개 추가
		Button btn1 = new Button("1");
		Button btn2 = new Button("2");
		setLayout(new FlowLayout());
		add(btn1);
		add(btn2);
		btn1.addActionListener(this);
		btn2.addActionListener(this);
		
		// 귀 만들기!(즉, 반응에 반응하게 만들기) > 리스터 만들어주면 됨
		// 그러나 리스너를 만들어주면 모두 설정해줘야하니깐 
		// 일부만 설정하기 위해 Adapter, 익명클래스 이용하여 종료 엑션이 동작하도록 만듦
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});

		setVisible(true);				// 창이 눈에 보이게 하려면 true를 줘야함
	}

	public static void main(String[] args) {
		new ButtonTest();
	} // end main()
	
} // end class

 

 

13. 자바 GUI는 거의 안쓰인다. 주로 C++ MFC를 훨씬 더 많이 사용한다. Why? 기능이 훨씬 더 좋기 때문에

 

14. 예외처리(Exception)

 : 에러가 발생하면 프로그램의 비정상적인 종료를 막을 길이 없지만,

   예외는 발생하더라도 프로그래머가 이에 대한 적절한 코드를 미리 작성해 놓음으로써

   프로그램의 비정상적인 종료를 막을 수 있다. 이것을 예외처리라고 한다.


   [에러] 심각한 오류 > 컴퓨터가 동작을 할 수 없을 정도의 오류
   [예외] 덜 심각한 오류 > 문법상 혹은 개발상 발생하는 덜 심각한 오류

   

   try {
       오류가 발생할 수 있는 문장;
   } catch(예외이름 객체명) {
       오류 발생시 실행할 문장;
   } finally {
       // 외부저장소 사용했을때 finally를 사용한다.

       // 언제? 외부저장소 close할 때...!
       // 잊지말자...! 외부저장소를 사용하기 위해 open했으면 반드시 다 사용 후 close를 해야한다.
       오류 발생 여부와 관계 없이 무조건 실행할 문장;
   }

   
   // finally 블록 말고 try catch문 끝난 다음에 코드 작성하면 무조건 실행됨

   // 그러나 외부 저장소는 무조건 finally에서 close해야한다는 점 명심...!



15. 클래스 이름 뒤에는 객체가 온다.

 

16. 예외처리 예제

** com.lec.java.exception > ExceptionTest.java

package com.lec.java.exception;

public class ExceptionTest {
	
	public static void main(String[] args) {
		
		try {
			System.out.println(10/0);
		} catch (ArithmeticException e) {
			System.out.println("0으로 나눌 수 없습니다.");
		}
		
	} // end main()

} // end class

 

 

17. 다음 수업 내용 : 예외처리, API, Object클래스, Wrapper클래스