2021. 04. 12(월) TIL

eastgun_·2021년 4월 12일
0

Java

중첩클래스

익명객체

  • 이름이 없는 객체다.
  • 주로 상위클래스를 상속받거나 인터페이스를 구현해서 즉석에서 객체를 생성하는 것이다.
  • 상위클래스나 인터페이스 없이 단독으로 객체를 생성할 수 없다.
  • 단 한번 사용되는 기능이 필요하다면 별도의 클래스 정의없이 익명객체로 생성하는 것이 유리하다.
    • 주로 GUI프로그램의 이벤트처리, 스레드 구현 등에 사용된다.
  • 적용예제
      //인터페이스
      public interface Pen {
        void draw();
      }
      //익명객체 
      Pen p = new Pen() {
        public void draw() {
          // 구현코드
        }
      };
      //인터페이스
      public inteface MouseListener {
        void mouseClicked(MouseEvent e);
        void mouseMoved(MouseEvent e);
      }
      //익명객체
      MouseListener listener = new MouseListener() {
        public void mouseClicked(MouseEvent e) {
          // 구현코드
        }
        public void mouseMoved(MouseEvent e) {
          // 구현코드
        }
      };

이벤트 모델

  • GUI 프로그램에서 사용자와 프 로그램이 서로 상호작용하도록 구현할 때 사용되는 모델
  • 주요 구성요소
    • Event
      - 사용자가 프로그램에서 어떤 행위를 했을 때 발생하는 사건
      - 마우스 움직이기, 버튼 클릭하기, 키보드 입력하기, 메뉴 선택하기 등
      - 사용자의 실행한 행위에 대한 정보를 갖고 있는 것이 Event다
      - 사용자가 프로그램에서 어떤 행위를 할 때 마다 Event라는 것이 만들어진다.
      - Event는 행위의 종류, 어디에서 했는지 등의 정보가 포함되어 있다
    • Event Source
      - Event가 발생하는 곳
      - 버튼, 메뉴, 아이콘, 콤보박스, 체크박스, 입력필드 등과 같은 각종 컴포넌트(GUI 프로그램의 구성하는 부품)
    • Event Handler(Evnet Listener)
      - Event가 발생했을 때 실행할 작업을 정의해 놓는 것
      - 자바에서는 Event의 종류에 따라서 EventHandler를 각각 구현해야 한다.
      - Event Handler로 구현해 놓은 작업은 해당 이벤트가 발생하면 JVM이 알아서 실행한다.
  • 이벤트를 이용한 상호작용 처리 프로세스
    1. 이벤트가 발생할 Event Source를 정한다

    2. 해당 Event Source에 발생하는 Event 중에서 어떤 Event를 사용할 지 정한다.

    3. 지정한 Event가 발생했을 때 실행할 Event Handler를 구현한다.

    4. 3번에서 작성한 EventHandler를 1번에서 지정한 Event Source와 연결한다.

    5. 1번에서 지정한 Event Source에서 2번에서 지정한 이벤트가 발생하면 3번에서 작성한 EventHandler를 실행한다.

package day6;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class GuiApp extends JFrame{

	
	JButton closeBtn = new JButton("닫기");
	JButton cancelBtn = new JButton("취소");
	JButton saveBtn = new JButton("저장");
	JButton exitBtn = new JButton("종료");
	
	public GuiApp() {
		
		setLayout(new FlowLayout(FlowLayout.CENTER, 100, 100));
		add(closeBtn);
		add(cancelBtn);
		add(saveBtn);
		add(exitBtn);
		
		// 이벤트 핸들러(이벤트 리스너) 작성하기
		// 버튼을 클릭했을 때, 입력필드에서 Enter키를 눌렀을 때는 ActionEvent가 발생한다.
		// 이벤트 소스 : JButton
		// 선정된 이벤트 : ActionEvent
		// 이벤트 핸들러 : ActionListener 인터페이스를 구현해서 작성한다.
		ActionListener listener1 = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println("저장이 완료되었습니다.");
			}
		};
		
		ActionListener listener2 = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println("프로그램을 종료합니다.");
			}
		};		
		
		// 람다표현식
		closeBtn.addActionListener(e -> System.out.println("닫기를 실행함"));
		
		// 이벤트소스에 이벤트핸들러(이벤트리스너) 연결하기
		cancelBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.out.println("실행을 취소합니다.");
			}
		});
		saveBtn.addActionListener(listener1);
		exitBtn.addActionListener(listener2);
		
		setVisible(true);
		setBounds(300, 300, 400, 200);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public static void main(String[] args) {
		new GuiApp();
	}
}

package day6;

public class Product {

	private String name;
	private String size;
	private int price;
	
	public Product(String name, String size, int price) {
		this.name = name;
		this.size = size;
		this.price = price;
	}

	public String getName() {
		return name;
	}

	public String getSize() {
		return size;
	}

	public int getPrice() {
		return price;
	}
}
package day6;

public class ProductApp2 {
	

	public static void main(String[] args) {
		Product[] products = new Product[10];
		products[0] = new Product("청바지", "S", 100000);
		products[1] = new Product("반바지", "M", 50000);
		products[2] = new Product("운동용바지", "L", 70000);
		products[3] = new Product("정장바지", "XL", 160000);
		products[4] = new Product("치마", "S", 80000);
		products[5] = new Product("스커트", "M", 120000);
		products[6] = new Product("린넨바지", "L", 30000);
		products[7] = new Product("카고바지", "XL", 200000);
		products[8] = new Product("나팔바지", "S", 110000);
		products[9] = new Product("면바지", "M", 40000);
		
		// 사이즈를 기준으로 재정의하는 메소드
		Predicate p1 = new Predicate() {
			// 상품의 사이즈가 "S"면 true를 반환하는 익명객체
			public boolean test(Product item) { 
				return item.getSize().equals("S");
			}
		};
		Predicate p2 = new Predicate() {
			// 상품의 가격이 5만원이면 true를 반환하는 익명객체
			public boolean test(Product item) { 
				return item.getPrice() == 50000;
			}
		};
		
		System.out.println("### 사이즈가 S인 상품만 출력");
		printProducts(products, p1);
		
		System.out.println("### 가격이 5만원인 상품만 출력");
		printProducts(products, p2);
		
		System.out.println("### 가격이 5만원 이상 10만원 이하인 상품만 출력");
		printProducts(products, new Predicate() {
			public boolean test(Product item) {
				return item.getPrice() >= 50000 && item.getPrice() <= 100000;
			}
		});
		
		System.out.println("### 사이즈가 S고 가격이 5만원 이상 10만원 이하인 상품만 출력");
		printProducts(products, new Predicate() {
			public boolean test(Product item) {
				return item.getSize().equals("S") && item.getPrice() >= 50000 && item.getPrice() <= 100000;
			}
		});
		
		System.out.println("### 람다 표현식으로 Predicate 인터페이스 구현하기");
		System.out.println("### 사이즈가 XL인 상품만 출력");
		printProducts(products, item -> {return item.getSize().equals("XL");});
		printProducts(products, item -> item.getSize().equals("XL"));
	}
	
	static interface Predicate {
		boolean test(Product item);
	}
	public static void printProducts(Product[] items, Predicate p) {
		for (Product item : items) {
			// 전달받은 Predicate 인터페이스의 구현객체에 구현된 test(item) 메소드를 실행한다.
			if (p.test(item)) {
				System.out.println(item.getName() + ", " + item.getSize() + ", " + item.getPrice());
			}
		}
	}
}

profile
게으르고 싶은 예비 개발자입니다.

0개의 댓글