웹_프론트_백엔드/JAVA프레임윅기반_풀스택

2020.03.27

shine94 2020. 3. 27. 09:01

1. List<>
 : 중복 허용, 순서 유지(인덱스 OK)


1) ArrayList<>
 : 참조 유리 / 삽입, 삭제, 추가 어려움 


2) LinkedList<>
 : 삽입, 삭제, 추가 용이 / 참조 불리

 


2. Set<>
 : 중복 불가, 순서 없음(인덱스 NO)


1) HashSet<>
 : 검색 속도


2) TreeSet<>
 : 정렬

 


3. Map<K, V>
1) HashMap<K, V>
 : 검색 속도


2) TreeMap<K, V>
 : 정렬

 

[실습코드]

 

1. [과제] 전화번호부 4.0 : CONTROLLER(PhonebookManager)만 수정하여 배열을 배열리스트로 자료구조 변경하기!

package phonebook04.list;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;

// CONTROLLER 객체
//	어플리케이션의 동작, 데이터 처리, (Business logic 담당)
public class PhonebookManager implements Pb {

	private ArrayList<PhonebookModel> pbList = new ArrayList<PhonebookModel>();
	
	// 몇 개의 데이터가 저장되었는지
	private int count = 0;
	
	// singleton 적용
	private PhonebookManager() {	}
	private static PhonebookManager instance = null;
	public static PhonebookManager getInstance() {
		if(instance == null) {
			instance = new PhonebookManager();
		}
		return instance;
	} // end getInstance()
	
	
	// 전화번호부 생성 등록
	@Override
	public int insert(String name, String phoneNum, String memo) {
		
		// 매개변수 검증 : 이름 필수
		if(name == null || name.trim().length() == 0) {
			throw new PhonebookException("insert() 이름입력오류 : ", Pb.ERR_EMPTY_STRING);
		}
		
		PhonebookModel model = new PhonebookModel((count + 1), name, phoneNum, memo, new Date());
		pbList.add(model);
		count++;
		
		return 1;
	}

	@Override
	public PhonebookModel[] selectAll() {
		return pbList.toArray(new PhonebookModel[pbList.size()]);
	}

	// 특정 uid 의 데이터 검색 리턴
	// 못찾으면 null 리턴
	@Override
	public PhonebookModel selectByUid(int uid) {
		
		for(int index = 0; index < count; index++) {
			if(index == uid) {
				return pbList.get(uid);
			}
		}
		
		return null;	// 못찾으면 null 리턴
	} // end selectByUid()

	@Override
	public int updateByUid(int uid, String name, String phoneNum, String memo) {
		// 매개변수 검증
		if(uid < 1) {
			throw new PhonebookException("update() uid 오류 : " + uid, Pb.ERR_UID); 
		}
		
		// 이름 필수
		if(name == null || name.trim().length() == 0) {
			throw new PhonebookException("update() 이름입력 오류 : ", Pb.ERR_EMPTY_STRING);
		}	
		
		// 특정 uid 값을 가진 데이터의 배열 인덱스 찾기
		int index = findIndexByUid(uid);
		
		if(index < 0) {
			throw new PhonebookException("update() 없는 uid", Pb.ERR_UID);
		}
		System.out.println(index);

		pbList.set((index - 1), new PhonebookModel((index),name, phoneNum, memo, new Date()));
		
		
		return 1;
	}

	@Override
	public int deleteByUid(int uid) {
		
		// 매개변수 검증
		if(uid < 1) {
			throw new PhonebookException("deleteByUid() uid 오류 : " + uid, Pb.ERR_UID); 
		}
		
		int index = findIndexByUid(uid);
		if(index < 0) {
			throw new PhonebookException("deleteByUid() 없는 uid", Pb.ERR_UID);
		}
		
		pbList.remove(uid-1);
		
		return 1;
	}
	
	// 현재 데이터 중 가능 큰 uid값을 찾아서 리턴
	private int getMaxUid() {
		int maxUid = 0;
		maxUid = count;
        
		return maxUid;
	}

	// 특정 uid 값을 가진 데이터의 배열 인덱스 찾기
	// 못찾으면 -1 리턴
	private int findIndexByUid(int uid) {
		
		for(int index = 0; index < count; index++) {
			if(index == uid) {
				System.out.println("findIndexByUid : "+uid);
				return uid;
			}
		}
		
		return -1;
	}
	
} // end PhonebookManager

// 예외 클래스 정의
// 예외발생하면 '에러 코드' + '에러 메시지'를 부여하여 관리하는게 좋다.
class PhonebookException extends RuntimeException{
	
	private int errCode = Pb.ERR_GENERIC;
	
	// 생성자 만들기
	public PhonebookException() {
		super("Phonebook 예외 발생");
	}
	
	public PhonebookException(String msg) {
		super(msg);
	}
	
	public PhonebookException(String msg, int errCode) {
		super(msg);
		this.errCode = errCode;
	}
	
	
	// Throwable 의 getMessage 를 오버라이딩 가능
	@Override
	public String getMessage() {
		String msg = "ERR-" + errCode + "]" +Pb.ERR_STR[errCode] 
				+ " " + super.getMessage();
		return msg;
	} 
	
} // PhonebookException

 

** 쌤이 선택한 학생의 코드..!!

package phonebook04.list;

import java.util.ArrayList;
import java.util.Arrays;

// CONTROLLER 객체
//   어플리케이션의 동작, 데이터 처리(CRUD), (Business logic 담당)

public class PhonebookManager implements Pb {
	
	private ArrayList<PhonebookModel> pbList = new ArrayList<PhonebookModel>();
	
	// singleton적용
	private PhonebookManager() {}
	private static PhonebookManager instance = null;
	public static PhonebookManager getInstance() {
		if (instance == null) {
			instance = new PhonebookManager();
		}
		return instance;
	} // end getInstance()	
	
	
	
	// 전화번호부 생성 등록
	@Override
	public int insert(String name, String phoneNum, String memo) {
		
		// 매개변수 검증 : 이름 필수
		if(name == null || name.trim().length() == 0) {
			throw new PhonebookException("insert() 이름입력오류: ", Pb.ERR_EMPTY_STRING);
		}
		
		PhonebookModel p = new PhonebookModel(name, phoneNum, memo);
		p.setUid(getMaxUid() + 1);
		pbList.add(p);
		
		return 1;
	}

	@Override
	public PhonebookModel[] selectAll() {
		PhonebookModel[] pb = new PhonebookModel[pbList.size()];
		for (int i = 0; i < pbList.size(); i++) {
			pb[i] = pbList.get(i);
		}
		return pb; 

		// 아래와 같이 한줄로 가능!  toArray() : List<> --> 배열로 변환
//		return pbList.toArray(new PhonebookModel[pbList.size()]);
	}

	// 특정 uid 의 데이터 검색 리턴
	// 못찾으면 null 리턴
	@Override
	public PhonebookModel selectByUid(int uid) {
		
		for (int i = 0; i < pbList.size(); i++) {
			if(pbList.get(i).getUid() == uid) {
				return pbList.get(i);
			}
		}
		
		return null;  // 못찾으면 null 리턴
	}// end selectByUid()

	@Override
	public int updateByUid(int uid, String name, String phoneNum, String memo) {
		
		// 매개변수 검증
		if(uid < 1)
			throw new PhonebookException("update() uid 오류: " + uid, Pb.ERR_UID);
		
		if(name == null || name.trim().length() == 0) // 이름 필수
			throw new PhonebookException("update() 이름입력 오류: ", Pb.ERR_EMPTY_STRING);
		
		// 특정 uid 값을 가진 데이터의 배열 인덱스 찾기
		int index = findIndexByUid(uid);
		if(index < 0) 
			throw new PhonebookException("update() 없는 uid: " + uid, Pb.ERR_UID);
		
		pbList.get(index).setName(name);
		pbList.get(index).setPhoneNum(phoneNum);
		pbList.get(index).setMemo(memo);
		
		return 1;
	}

	@Override
	public int deleteByUid(int uid) {
		// 매개변수 검증
		if(uid < 1) 
			throw new PhonebookException("deleteByUid() uid 오류: " + uid, Pb.ERR_UID);
		
		int index = findIndexByUid(uid);
		if(index < 0)
			throw new PhonebookException("deleteByUid() 없는 uid: " + uid, Pb.ERR_UID);

		pbList.remove(index);
		
		return 1;
	}
	
	// 현재 데이터중 가장 큰 uid 값을 찾아서 리턴
	private int getMaxUid() {
		int maxUid = 0;
		
		if(pbList.size() > 0) {
			int uid = pbList.get((pbList.size() - 1)).getUid();
			if(maxUid < uid) maxUid = uid;
		}
		
//		for (PhonebookModel p : pbList) {
//		if(maxUid < p.getUid()) {
//			maxUid = p.getUid();
//		}
//	}
		
		return maxUid;
	}
	
	// 특정 uid 값을 가진 데이터의 배열 인덱스 찾기
	// 못찾으면 -1 리턴
	private int findIndexByUid(int uid) {
		
		for (int i = 0; i < pbList.size(); i++) {
			if(pbList.get(i).getUid() == uid) return i;
		}
		
		return -1;
	}
	

} // end PhonebookManager

// 예의 클래스 정의
// 예외발생하면 '에러코드' + '에러메세지'를 부여하여 관리하는게 좋다.
class PhonebookException extends RuntimeException {
	
	private int errCode = Pb.ERR_GENERIC;
	
	public PhonebookException() {
		super("Phonebook 예외 발생");
	}
	
	public PhonebookException(String msg) {
		super(msg);
	}
	
	public PhonebookException(String msg, int errCode) {
		super(msg);
		this.errCode = errCode;
	}
	
	
	// Throwable 의 getMessage 를 오버라이딩 가능
	@Override
	public String getMessage() {
		String msg = "ERR-" + errCode + "]" + Pb.ERR_STR[errCode] +
					" " + super.getMessage();
		return msg;
	}
	
} // end PhonebookException

 

 

2. Lec22_Collection
1) com.lec.java.collection14 패키지, Collection14Main 클래스

package com.lec.java.collection14;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
/* java.util.Collections 클래스
	 Collections 클래스는 여러 유용한 알고리즘을 구현한 메소드들을 제공
	 대부분 클래스메소드 (static) 형태로 제공됨
	 
	 정렬(sort)
	 섞기(shuffle)
	 탐색(search)
 */
public class Collection14Main {

	public static void main(String[] args) throws ParseException {
		System.out.println("Collections 메소드");

		List<String> list1 = new LinkedList<String>();
		
		list1.add("장수영");
		list1.add("김진영");
		list1.add("고유성");
		
		System.out.println(list1);	// List 의 toSting 결과 형태 출력
		
		System.out.println("sort()");
		// sort()
		// 기본적으로 속도가 비교적 빠르고 안전성이 보장되는 Merge Sort 사용
		Collections.sort(list1);
		System.out.println(list1);	// 정렬 후 결과!
		
		System.out.println();
		List<Date> list2 = new LinkedList<Date>();
		// 문자열 "2018-08-16" --> Date객체
		list2.add(new SimpleDateFormat("yyyy-MM-dd").parse("2018-08-16"));
		list2.add(new SimpleDateFormat("yyyy-MM-dd").parse("2017-05-21"));
		list2.add(new SimpleDateFormat("yyyy-MM-dd").parse("2022-03-03"));
		System.out.println(list2);
		Collections.sort(list2);
		System.out.println(list2);	// 날짜 오름차순으로 정렬
		
		// String 타입이면 알파벳 순으로 정렬된다.
		// Date 타입이면 날짜순으로 정렬된다
		// ★ String 과 Date 는 기본적으로 Comparable<T> 인터페이스가 구현되었기 때문.
		// ※ String 온라인 도움말 확인해보자
	
		System.out.println();
		List<Student> list3 = new LinkedList<Student>();
		list3.add(new Student("Susie", 50));
		list3.add(new Student("James", 80));
		list3.add(new Student("Kevin", 30));
		System.out.println(list3);

		

		System.out.println();
		System.out.println("Comparable 구현, sort() 적용");
		// Student 에 Comparable<> 구현 안되어 있으면 에러..!!
		// 만약 Comparable<> 구현 전에 컴파일 하면 아래와 같은 에러 발생
		// The method sort(List<T>) in the type Collections 
		// is not applicable for the arguments(List<Student>)
		// Comparable<> 구현하면 사용 가능해지면서 대소 비교가 가능해짐...!!
		Collections.sort(list3);	
		// Comparable<> 구현 후 실행
		System.out.println(list3);	// 정렬 후 출력
		
		// 역순 정렬
		System.out.println();
		System.out.println("reverseOrder() 적용");
		Collections.sort(list3, Collections.reverseOrder());
		System.out.println(list3);
		
		System.out.println();
		System.out.println("reverse() 적용");
		Collections.reverse(list3);
		System.out.println(list3);
		
		
		// Comparator<> 적용
		// Collections.sort 메소드는 두 번째 인자로 Comparator 인터페이스를 받을 수 있도록 해놓았습니다.
		// Comparator 인터페이스의 compare 메소드를 오버라이드 하면 됩니다.
		System.out.println("Comparator<> 적용");
		Collections.sort(list3, new Asc());		// '이름' 오름차순
		System.out.println(list3);
		
		// '이름' 내림차순
		Collections.sort(list3, new Desc());		// '이름' 오름차순
		System.out.println(list3);
		
        
		// Collections 에서 많이 쓰이는 인터페이스임
		// Comparable 은 클래스 자체에 구현하는 인터페이스  compareTo(자기사진 vs 매개변수)
		// Comparator 는 두개의 객체 비교하는 기능제공 인터페이스  compare(매개변수1 vs 매개변수2)
		//      구현된 객체가 매개변수 등에 넘겨지는 형태로 많이 쓰임
		
        
		// Shuffling 하기 (섞기)
		System.out.println();
		System.out.println("shuffle()");
		Collections.shuffle(list1);
		System.out.println(list1);
		Collections.shuffle(list1);
		System.out.println(list1);
		
		// 배열에서 랜덤으로 3명만 뽑기
		String[] arr = {"안녕", "하세요", "치킨", "먹고 싶어요", "집에 가고 싶다", 
			"잠도 자고 싶다", "잠이 부족해", "탈주하고 싶다", "도망가고 싶다"};
		List<String> arrList = Arrays.asList(arr);	// 배열 --> List<>	 
								// ( List<> 의 toArray() 의 반대)
		Collections.shuffle(arrList);
		arrList = arrList.subList(0, 3);	// index 0부터 3전까지의 List<> 생성
		System.out.println(arrList);
		
		
		// min(), max()
		// Comparable 메소드 영향 받음
		System.out.println();
		System.out.println("min(), max()");
		System.out.println(Collections.min(list1));
		System.out.println(Collections.max(list1));
		System.out.println(Collections.min(list3));
		System.out.println(Collections.max(list3));
		
		
		// copy()
		System.out.println();
		List<Student> list4 = new LinkedList<Student>();
		list4.add(new Student("aaa", 10));
		list4.add(new Student("bbb", 20));
		list4.add(new Student("ccc", 30));
		
		System.out.println("copy() 전");
		System.out.println(list4);
		System.out.println("copy() 후");
		Collections.copy(list4, list3);
		System.out.println(list4);
		
		System.out.println("\n프로그램 종료");
	} // end main

} // end class


// 처음은 Comparable 구현 없이 해보고, 
// 에러 확인한 다음에는 Student 클래스에서 Comparable 구현한 뒤 
// 메인 메소드에서 Collections.sort(list3) 출력해보기
class Student implements Comparable<Student>{
	String name;
	double point;
	
	public Student(String name, double point) {
		super();
		this.name = name;
		this.point = point;
	}
	
	@Override
	public String toString() {
		return this.name + ":" + this.point + "점";
	}

	// compareTo() 메소드는 매개변수 객체를 '자신'과 비교하여
	// 작으면 음수, 같으면 0, 크면 양수를 리턴한다.
	@Override
	public int compareTo(Student o) {
		
		// 점수 오름차순
//		if(o.point > this.point) return -1;  // 내가 더 작으면 음수
//		if(this.point > o.point) return 1;   // 내가 더 크면 양수
//		return 0;  // 같으면 0
		
		// 점수 내림차순
		if(o.point < this.point) return -1;  // 내가 더 작으면 음수
		if(this.point < o.point) return 1;   // 내가 더 크면 양수
		return 0;  // 같으면 0		
		
	}

} // end class

// Student를 이름(name) 오름차순으로 정렬해줄 수 있는 Comparator<> 제공
class Asc implements Comparator<Student> {

	@Override
	public int compare(Student o1, Student o2) {
		// 이름
		return o1.name.compareTo(o2.name);
	}

} // end Asc


// Student를 이름(name) 내림차순으로 정렬해줄 수 있는 Comparator<> 제공
class Desc implements Comparator<Student> {

	@Override
	public int compare(Student o1, Student o2) {
		// 이름
		return o2.name.compareTo(o1.name);
	}

} // end Asc

 

 

3. Lec31_Java_Util
1) com.lec.java.datetime01 패키지, DateTime01Main 클래스

package com.lec.java.datetime01;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/*
 * 날짜를 다루기 위해 자바에선 java.util.Date 클래스 제공   JDK 1.0 부터..
 * 이후 보완하여 java.util.Calendar 등장   JDK 1.1 부터..
 * java.time 패키지 제공 JDK 1.8 (Java8)부터
 * 
 * 지금은 java.time 패키지만으로 충분하긴 하나.. 
 * 오랜시간 Date, Calendar 를 사용하여 만들었으므로 이 또한 알긴 알아야 한다
 * 
 */
public class DateTime01Main {

	public static void main(String[] args) throws Exception{
		System.out.println("Date객체로 날짜 다루기");

		// 현재 날짜 얻어오기,  생성자가 현재 날짜, 시간을 얻어온다.
		Date now = new Date();		// import java.util.date;
		String strNow = now.toString();
		
		System.out.println("1. Date 의 toString() 사용한 출력");
		System.out.println(strNow);
		
		System.out.println();
		System.out.println("2. Date 의 get..()을 사용한 출력");
		// Date객체의 대부분의 메소드들은 현재 deprecated 됨.
		int year = now.getYear() + 1900;	// 연도는 1900 이후 경과 년도
		int month = now.getMonth() + 1;		// 시작을 0부터
		int day= now.getDate();			// 날짜
		int weekDay = now.getDay();		// 요일 : 일요일이 0
		int hour = now.getHours();
		int minute = now.getMinutes();
		int second = now.getSeconds();
		System.out.println(year + "년 " + month + "월 " + day + "일 "
				+ hour + "시 " + minute + "분 " + second + "초");
		
		
		System.out.println();
		System.out.println("3. SimpleDateFormat 사용한 출력");
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy년 MM월 dd일 hh시 mm분 ss초");
		String strNow2 = fmt.format(now);
		System.out.println(strNow2);

		
		// yyyy-MM-dd hh:mm:ss 형식 출력
		// 포맷에 사용되는 문자열 종류 : 자바의 정석 교재 p544
		// H: 시간 (0~23),  h : 시간 (1~12)
		System.out.println(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
		
		// ※ 현재 Date() 객체는 생성자를 제외하고는 거의다 deprecated 되어 있다.
		
		System.out.println();
		System.out.println("Date 테스트");
		long baseTime = System.currentTimeMillis();	// 현재시간을 ms로 리턴
								// 1970-01-01 00:00:00 UTC 기준으로 경과된 ms
		//System.out.println(baseTime);
		long surTime = baseTime + 2000; 	// 2초 뒤의 시간값 ms
		
		SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss", Locale.KOREA);
		String mTime = mSimpleDateFormat.format(new Date(baseTime));
		String mTime2 = mSimpleDateFormat.format(new Date(surTime));
		System.out.println(mTime);
		System.out.println(mTime2);
		
		
		// 문자열을 Date 타입으로 파싱하기
		System.out.println();
		System.out.println("문자열 -> Date");
		String oldstring = "2018-08-16 14:21:52.3";

		Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S", Locale.KOREA).parse(oldstring);
		System.out.println(date);
		
		
		// 경과시간 체크하기
		System.out.println();
		System.out.println("경과시간");
		long start = System.currentTimeMillis();
		for(int i = 0; i < 5; i ++) {
			System.out.println(i);
			Thread.sleep(1000);	// 1초간 딜레이
		}
		long end = System.currentTimeMillis();
		long lapTime = end - start;	// 경과시간
		System.out.println("경과시간 : " + lapTime + " ms");
		
		// nanosec : 10E-9초
		start = System.nanoTime();
		end = System.nanoTime();
		
		System.out.println();
		System.out.println("millisec -> time");
		long durationInMillis = 1000000;
		long millis = durationInMillis % 1000;
		long sec = (durationInMillis / 1000) % 60;
		long min = (durationInMillis / (1000 * 60)) % 60;
		long hr = (durationInMillis / (1000 * 60 * 60)) % 24;
		
		String time = String.format("%02d:%02d:%02d.%03d", hr, min, sec, millis);
		System.out.println(time);
		
	} // end main()

} // end class

 

[추가] Date객체 대부분의 메소드들은 현재 deprecated됨(곧 사라질 코드이기 때문에 사용을 권장하지 않는다는 뜻)

2) com.lec.java.datetime02 패키지, DateTime02Main 클래스

package com.lec.java.datetime02;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
/*
   Calendar 객체
   
   Calendar 는 추상클래스다.  그래서 new로 생성 불가.
     날짜와 시간을 계산하는 방식(역법) 지역, 문화, 나라에 따라 다르기 때문에
     이를 상속받아 개별적으로 구현함
   
   Calendar 는 날짜/시간을 계산하는 꼭 필요한 메소드만 제공하고
     특정한 역법(날싸 시간계산 ex: 음력) 은 상속받은 클래스에서 구현
   
     특별히 상속할 필요 없으면 getInstance() static 메소드 호출
 */
public class DateTime02Main {

	public static void main(String[] args) {
		System.out.println("Calendar객체로 날짜 다루기");
		
		//  특별한 역법을 쓰지 않는 경우.  우리나라 서력 사용.
		Calendar cal = Calendar.getInstance();

		
		System.out.println("get() 으로 날짜/시간 받아오기");
		System.out.println("현재:");
		// get(int field)
		printDate(cal);
		

		System.out.println();
		System.out.println("TimeZone");
		TimeZone timezone = TimeZone.getTimeZone("America/Los_Angeles");
		cal = Calendar.getInstance(timezone);	// 매개변수 TimeZone!
		printDate(cal);
		
		System.out.println();
		// 시간대 문자열들 획득
		String[] availableIDs = TimeZone.getAvailableIDs();
		for(String id : availableIDs) {
			System.out.println(id);
		}
		
		System.out.println();
		System.out.println("Date ↔ Calendar 변환");
		// 상호간에 변환할 일이 생긴다..
		
		// 1-1. Calendar -> Date
		cal = Calendar.getInstance();
		Date date = cal.getTime();
		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
		
		// 1-2 Calendar -> Date
		date = new Date(cal.getTimeInMillis());
		System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date));
		
		// 2. Date -> Calendar
		cal.setTime(date);
		printDate(cal);
		
		
		// 오늘날 우리 대한민국이 쓰는 달력은 GregorianCalendar(국제표준시) 이며
		// 이는 Calendar 를 상속받은 클래스입니다.
		// 기본적으로 시스템 설정 시각 (서울)으로 되어 있으며
		// Locale 값을 설정하면 특정 지역 시각을 알수 있습니다.
		System.out.println();
		System.out.println("GregorianCalendar 사용");
		GregorianCalendar gregCal = new GregorianCalendar();
		printDate(gregCal);
		
		int year = 2020;
		System.out.println(year + " 는 윤년? " + gregCal.isLeapYear(year));
	} // end main()
	
	public static void printDate(Calendar now) {
		
		int year = now.get(Calendar.YEAR);            // 연도 리턴
		int month = now.get(Calendar.MONTH) + 1;    // 월을 리턴  0 ~ 11
		int day = now.get(Calendar.DAY_OF_MONTH);    // 일을 리턴
		
		int week = now.get(Calendar.DAY_OF_WEEK);    // 요일을 리턴   일요일: 1 ~ 토요일: 7
		int ampm = now.get(Calendar.AM_PM);          // AM 0  PM 1
		int hour = now.get(Calendar.HOUR);
		int minute = now.get(Calendar.MINUTE);
		int second = now.get(Calendar.SECOND);
		
		String strWeek = null;
		switch(week) {
		case Calendar.MONDAY:
			strWeek = "월";
			break;
		case Calendar.TUESDAY:
			strWeek = "화";
			break;
		case Calendar.WEDNESDAY:
			strWeek = "수";
			break;
		case Calendar.THURSDAY:
			strWeek = "목";
			break;
		case Calendar.FRIDAY:
			strWeek = "금";
			break;
		case Calendar.SATURDAY:
			strWeek = "토";
			break;
		case Calendar.SUNDAY:
			strWeek = "일";
			break;
		}
		
		String strAmPm = null;
		switch(ampm) {
		case Calendar.AM:
			strAmPm = "오전";
			break;
		case Calendar.PM:
			strAmPm = "오후";
			break;
		}
		
		System.out.println(year + "-" + month + "-" + day + " " + strWeek);
		System.out.println(strAmPm + " " + hour + ":" + minute + ":" + second);
	} // end printDate()
	
} // end class

 

3) com.lec.java.datetime03 패키지, DateTime03Main 클래스

package com.lec.java.datetime03;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/* Calendar 객체를 사용한 시간 및 날짜 연산
 *  
 */
public class DateTime03Main {

	public static void main(String[] args) {
		System.out.println("날짜, 시간 연산");

		Calendar cal = Calendar.getInstance();
		DateFormat df = null;
		Date date = null;
		
		//-------------------------------------------------------
		System.out.println("현재 시간에서 날짜 더하고 빼기");
		
		cal.setTime(new Date());	// 현재 시간
		df = new SimpleDateFormat("yyyy-MM-dd");
		System.out.println("현재 : " + df.format(cal.getTime()));
		
		//cal.add(Calendar.MONTH, 2);
		//cal.add(Calendar.MONTH, 11);
		//cal.add(Calendar.MONTH, -4);
		cal.add(Calendar.DATE, 3);
		
		System.out.println("계산 후 : " + df.format(cal.getTime()));
        //-------------------------------------------------------
        System.out.println();
        System.out.println("특정 날짜에 더하고 빼기");
        
        df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        
        try {
			date = df.parse("2020-03-16 09:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
        cal.setTime(date);
        System.out.println("주어진 시간 : " + df.format(cal.getTime()));
        cal.add(Calendar.HOUR_OF_DAY, 5);
        cal.add(Calendar.MINUTE, 20);
        cal.add(Calendar.SECOND, 10);
        System.out.println("계산 후 시간 : " + df.format(cal.getTime()));
        
        //-------------------------------------------------------
        System.out.println();
        System.out.println("날짜 두개 더하기");
        // 두개의 Date를 더하려면 두개의 Calendar를 사용해야 합니다. 

        Calendar cal2 = Calendar.getInstance();
        System.out.println("cal: " + df.format(cal.getTime()));
        System.out.println("cal2: " + df.format(cal2.getTime()));
        
        cal.add(Calendar.DATE, -cal2.get(Calendar.DATE));

        System.out.println("날짜 두개 계산후");
        System.out.println("cal: " + df.format(cal.getTime()));
        System.out.println("cal2: " + df.format(cal2.getTime()));
        
		System.out.println("\n프로그램 종료");
	} // end main()

} // end class

 

 

4. Lec23_InnerClass
1) com.lec.java.inner01 패키지, Inner01Main, TestOuter 클래스

** Inner01Main 클래스

package com.lec.java.inner01;
/*
 Inner Class(내부 클래스)
 1. Member inner class(멤버 내부 클래스): 다른 클래스 내부에서 선언된 클래스
 2. Static inner class(static 내부 클래스): 다른 클래스의 내부에서 static으로 선언된 클래스
 3. Local class(지역 클래스)
   1) Local inner class(지역 내부 클래스): 메소드 내부에서 선언된 클래스
   2) Anonymous inner class(익명 내부 클래스): 이름이 없는 local class
*/
public class Inner01Main {

	public static void main(String[] args) {
		System.out.println("Member Inner Class(멤버 내부 클래스)");
		
		// 외부 클래스의 인스턴스
		TestOuter out = new TestOuter(100);
		
		// 멤버 내부 클래스의 인스턴스 생성
		// 멤버 내부 클래스의 이름: [외부클래스 이름].[멤버 내부클래스 이름]
		// [외부클래스 이름].[내부클래스 이름] 참조변수 =
		//      [외부클래스 인스턴스].new 내부클래스 생성자();
		TestOuter.TestInner in = out.new TestInner(111);
		in.printOuterValue();
		in.printInnerValue();
		
		System.out.println();
		// 하나의 외부 클래스 인스턴스를 이용해서
		// 멤버 내부 클래스의 인스턴스는 여러개 생성 가능.
		TestOuter.TestInner in2 = out.new TestInner(123);
		in2.printOuterValue();
		in2.printInnerValue();
		
		// 새로운 외부 클래스 인스턴스 생성
		// out2 외부 클래스 인스턴스 생성
		// out2 로부터 in4, in5라는 이름으로 내부 클래스 객체 만드세요
		TestOuter out2 = new TestOuter(200);
		
		System.out.println();
		TestOuter.TestInner in4 = out2.new TestInner(201);
		in4.printOuterValue();
		in4.printInnerValue();

		System.out.println();
		TestOuter.TestInner in5 = out2.new TestInner(202);
		in5.printOuterValue();
		in5.printInnerValue();
		
		System.out.println();
		TestOuter.TestInner in7 = new TestOuter(30).new TestInner(330);
		in7.printOuterValue();
		in7.printInnerValue();
		
	} // end main()

} // end class Inner01Main

 

** TestOuter 클래스

package com.lec.java.inner01;
/*
 	Member inner class(멤버 내부 클래스)
 	
	TestOuter 클래스 내부에서 TestInner 클래스를 정의
	TestOuter: 외부 클래스(Outer Class, Enclosing Class)
	TestInner: 멤버 내부 클래스(Member Inner Class)
	1) 멤버 내부 클래스는 외부 클래스의 인스턴스가 생성된 이후에야 
	인스턴스 생성이 가능함.
	2) 멤버 내부 클래스는 외부 클래스의 모든 멤버들(private 포함)을 사용 가능
*/
// 클래스: 멤버 변수들 (+ 생성자들) + 멤버 메소드들 = 데이터 타입
public class TestOuter {
	// 멤버 변수:
	private int value;
	
	// 생성자:
	public TestOuter() {}
	public TestOuter(int value) {
		this.value = value;
	}
	
	// 메소드:
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}

	
	// Member Inner Class 정의
	// (수식어) class 클래스 이름{ ... }
	public class TestInner{
		// 멤버변수
		private int innervalue;
		
		
		// 생성자
		public TestInner() {}
		public TestInner(int val) {
			this.innervalue = val;
		}
		
		// 멤버메소드
		public void printOuterValue() {
			System.out.println("value = " + value);
			// Member inner class 에서는
			// 외부클래스(outer class) 의
			// 멤버를 직접 접근 가능
		}
		
		public void printInnerValue() {
			System.out.println("innerValue = " + innervalue);
		}
		
	} // end TestInner
    
	
} // end class TestOuter

 

2) com.lec.java.inner02 패키지, Inner02Main, Car 클래스

** Inner02Main 클래스

package com.lec.java.inner02;
/*
 	언제 내부 클래스로 설계?  
 	
	 상속 관계로 묶을 수는 없지만,
	 A라는 객체가 생성된 이후에야 존재할 수 있는 B라는 객체가 있다고 한다면,
	 B를 A의 멤버 '내부 클래스'로 선언한다.
	 (예) 컴퓨터-CPU/메모리, 자동차-타이어
	
	 반면
	 '햄버거 세트 메뉴' 객체의 경우
	  햄버거 객체와 콜라 객체는 별개의 객체로도 존재 가능하니까
 	 '햄버거' 와 '콜라' 는 '세트메뉴' 객체의 '멤버변수'로 붙도록 하는게 낳다
 	
 	is-a  : 상속관계
 	has-a (종속) : 멤버내부클래스
 	has-a (독립) : 멤버변수
 	
 */
public class Inner02Main {

	public static void main(String[] args) {
		System.out.println("멤버 내부 클래스 활용");
		
		Car myCar = new Car("Hot Pink");
		Car.Tire myTire1 = myCar.new Tire(17);
		
		myTire1.displayInfo();
		Car.Tire myTire2 = myCar.new Tire(27);
		Car.Tire myTire3 = myCar.new Tire(41);
		
		myTire2.displayInfo();
		myTire3.displayInfo();
	
	} // end main()

} // end class Inner02Main

 

** Car 클래스

package com.lec.java.inner02;

public class Car {
	// 멤버 변수( outer )
	private String color;
	
	// 생성자
	public Car(String color) {
		this.color = color;
	}
	
	// 메소드
	public void displayCarInfo() {
		System.out.println("color: " + color);
	}
	
	
	// 멤버 내부 클래스
	public class Tire {
		
		private int radius;
		
		public Tire(int radius) {
			this.radius = radius;
		}
		
		public void displayInfo() {
			System.out.println("--- 자동차 정보 ---");
			System.out.println("color : " + color);
			System.out.println("tire : " + radius);
		}
	}
	
    
} // end class Car


3) com.lec.java.inner03 패키지, Inner03Main, TestOuter 클래스

** Inner03Main 클래스

package com.lec.java.inner03;

public class Inner03Main {

	public static void main(String[] args) {
		System.out.println("외부/내부 클래스의 this");
		
		TestOuter out = new TestOuter(100);
		TestOuter.TestInner in1 = out.new TestInner(111);
		in1.printValue();

	} // end main()

} // end class Inner03Main

 

** TestOuter 클래스

package com.lec.java.inner03;

public class TestOuter {
	private int value;
	
	public TestOuter(int value) {
		this.value = value;	// 1. Outer value
	}
	
	public int getValue() {
		return value;
	}
	
	// 멤버 내부 클래스
	public class TestInner{
		private int value;	// 2. Inner value
		
		public TestInner(int value) {
			this.value = value;
		}
		
		public void printValue() {
			int value = 10;			// 3. 지역변수 value
            
			System.out.println("value = " + value);			// 3번
			System.out.println("this.value = " + this.value);	// 2번
			System.out.println("TestOuter.this.value = " + TestOuter.this.value);	// 1번
		}
	}
	

} // end class TestOuter

 

4) com.lec.java.inner04 패키지, Nested01Main, TestOuter 클래스 

** Nested01Main 클래스

package com.lec.java.inner04;
/*
 Nested Class(중첩 클래스):
    다른 클래스의 내부에서 멤버로 정의된 클래스인데, 
  static 키워드가 사용된 내부 클래스 (static inner class)
   
   static: 클래스의 인스턴스가 생성되지 않아도 사용될 수 있는 멤버(변수, 메소드)에 사용
      따라서, nested class는 외부 클래스의 인스턴스를 생성하지 않고,
      내부 클래스의 인스턴스를 생성할 수 있다.
   
   nested(static) class는 
   (외부 클래스에서) static으로 선언된 변수와 메소드만 사용 가능
   
	중첩 클래스의 인스턴스 생성:
		타입 참조변수 = new 생성자()
		중첩 클래스의 이름(타입): [외부클래스 이름].[내부클래스 이름]
		중첩 클래스의 생성자: new [외부클래스 이름].생성자()

*/
public class Nested01Main {

	public static void main(String[] args) {
		System.out.println("Nested Class(중첩 클래스): static inner class");

		TestOuter.TestNested nest1 = new TestOuter.TestNested();
		nest1.displayInfo();
		
	} // end main()

} // end class Nested01Main

 

** TestOuter 클래스

package com.lec.java.inner04;

public class TestOuter {

	// 멤버변수
	private int value;  // 인스턴스 변수
	private static int count = 100; // 클래스 변수 (static)
	
	// 생성자
	public TestOuter(int value) {
		this.value = value;
	}
	
	// Nested class (static inner class)
	// static 안에서는 static 밖에 못쓴다!
	public static class TestNested {
		
		public void displayInfo() {
			// static 클래스에서는 외부클래스의
			// non-static 멤버 사용 불가
			// 그렇기 때문에 아래의 코드는 에러
			//System.out.println("value = " + value); 
			
			System.out.println("count = " + count);
		}
		
	} // end TestNested
	
    
} // end class TestOuter


// TestOuter: 외부 클래스(outer class, enclosing class)
// TestNested: 중첩 클래스(nested class, static inner class)

 

5) com.lec.java.inner05 패키지, Local01Main, TestOuter 클래스
** Local01Main 클래스

package com.lec.java.inner05;
/*
 Local Inner Class: 블록({ ... }) 내부에서 정의된 클래스
   1. 정의가 된 블록(메소드) 내부에서만 사용 가능 - 참조변수 선언, 인스턴스 생성
   2. 접근 수식어(public, protected, private)는 쓸 수 없다.
   3. 외부 클래스의 멤버 변수(private 포함)는 모두 사용 가능
   4. effectively final인 지역변수나 매개변수만 사용 가능
 
 effectively final 변수란?
  1) final로 선언된 변수, 또는
  2) 한 번 초기화가 된 이후로 값이 변경되지 않은 변수(Java 8에서 도입)
*/
public class Local01Main {

	public static void main(String[] args) {
		System.out.println("Local Inner Class(지역 내부 클래스)");
		
		TestOuter out = new TestOuter();
		out.localMethod(600);

	} // end main()

} // end class Local01Main


** TestOuter 클래스

package com.lec.java.inner05;

public class TestOuter {
	// TestOuter 클래스의 멤버 변수
	private int num1 = 100;
	
	// TestOuter 클래스의 멤버 메소드
	public void localMethod(final int num4) {
		int num2 = 200; 	// localMethod() 의 지역변수
		
        
		// Local inner class
		class TestLocal {
			// 멤버변수
			private int num3 = 300;
			int num5 = 500;
			
			// 멤버메소드
			public void showNumber() {
				System.out.println("num1 = " + num1);	// 외부클래스의 멤버
				System.out.println("num2 = " + num2);	// class와 같은 local 의 지역변수
				System.out.println("num3 = " + num3);	// 자기 자신 의 멤버변수
				System.out.println("num4 = " + num4);
				System.out.println("num5 = " + num5);
			}
		} // end class TestLocal
		
        
		TestLocal local = new TestLocal();
		//num2 = 400;	// 에러 발생
				// num2 값을 변경하면.. 아래 showNumbers()에선
				// 200 이 찍혀야 하나? 400이 찍혀야 하나?
				// 그래서 로컬내부클래스에서 사용 가능한 지역의 변수는 
				// 반드시 effectively final 이어야 한다
				// 	  즉 한번 초기화 된후 값이 변경되지 않거나, final 이어야 한다.
		
		local.showNumber();
		
	} // end localMethod()
	
} // end class TestOuter


[추가] Local Inner Class는 지역변수와 매개변수는 effectively final 변수만 사용 가능

         effectively final 변수란? final로 선언된 변수, 한 번 초기화가 된 이후로 값이 변경되지 않은 변수

6) com.lec.java.inner06 패키지, Local02Main, Person 클래스

** Local02Main 클래스

package com.lec.java.inner06;

public class Local02Main {

	public static void main(String[] args) {
		System.out.println("Local 내부 클래스의 활용");
		
		Person person = new Person("ABC");
		Readable r = person.createInstance(40);
		r.readInfo();

	} // end main()

} // end class Local02Main

 

** Person 클래스

package com.lec.java.inner06;

public class Person {
	// Person 외부 클래스의 멤버 변수
	private String name;
	
	// Person 외부 클래스의 생성자
	public Person(String name) {
		this.name = name;
	}
	

	/*
	// 지역 클래스는 메소드 실행이 끝나게 되면 정의 자체가 사라지게 되는 클래스이다!!
	// 메소드 내부에 정의된 지역 클래스 타입을 리턴하는 메소드는 만들 수 없다
	// 그렇기 때문에 아래의 코드는 불가능한 코드!!
	// 가능하게 만드는 코드가 있는데 아래의 코드가 그러한 코드이면서 설명이 기재되어 있음!
	public PersonAge createInstance(int age) {
		
		// Local inner class
		class PersonAge {
			public void readInfo() {
				System.out.println("이름 " + name);
				System.out.println("나이 " + age);
			}
		}
		
		PersonAge p = new PersonAge();
		
		return p;
		
	} // end createInstance()
	*/
	
	
	// 2. 메소드의 리턴타입은 정의한 인터페이스 타입으로 정의
	public Readable createInstance(int age) {
		
		// 3. 로컬 클래스는 인터페이스를 구현(implements)하도록 정의
		class PersonAge implements Readable{
			// 여기서 중요한 점...!!
			// readInfo를 위해서 PersonAge 클래스 만들어서 잠깐 사용한거임...!!
			// 잠깐 사용할 클래스에 이름 짓고 클래스 만들기 너무 귀찮아..!! 비효율적이야!!
			// 이래서 생긴 것이 익명 클래스!!!!! -> Anonymous inner class

			@Override
			public void readInfo() {
				System.out.println("이름 : " + name);
				System.out.println("나이 : " + age);
			}
		} //end PersonAge
		
		// 4. 로컬 클래스의 인스턴스를 생성하고 리턴해줌
		Readable person = new PersonAge();	// 다형성!!
		return person;
		
	} // end createInstance()
	
/*
 지역 클래스는 메소드 실행이 끝나게 되면 정의 자체가 사라지게 되는 클래스임.
 메소드 내부에 정의된 지역 클래스 타입을 리턴하는 메소드는 만들 수 없다.
 경우에 따라서는, 지역 클래스에 정의된 메소드를
 외부에서 직접 사용하고자 하는 경우가 발생할 수도 있습니다.
 그걸 가능하게 하는 방법이 

 인터페이스(interface) + 다형성(polymorphism):
 
 1. 외부에서 사용하고 싶은 메소드를 선언한 인터페이스를 작성
 2. 메소드의 리턴타입은 정의한 인터페이스 타입으로 정의
 3. 로컬 클래스는 인터페이스를 구현(implements)하도록 정의
 4. 로컬 클래스의 인스턴스를 생성하고 리턴해줌
*/

} // end class Person

// 1. 외부에서 사용하고 싶은 메소드를 선언한 인터페이스를 작성
interface Readable {
	public abstract void readInfo();
}


7) com.lec.java.inner07 패키지, Anonymous01Main, Person 클래스

** Anonymous01Main 클래스

package com.lec.java.inner07;
/*
  Anonymous inner class(익명 내부 클래스):
   이름이 없는 local inner class
   이름이 없기 때문에 생성자를 만들 수가 없습니다.
   클래스의 정의와 동시에 인스턴스를 생성합니다.
*/
// 익명클래스는 : 인터페이스, 추상클래스, 일반클래스 모두 가능하다
public class Anonymous01Main {

	public static void main(String[] args) {
		System.out.println("Anonymous Inner Class(익명 내부 클래스)");
		
		// 1)
		Person p = new Person("헐크");
		Readable r = p.createInstance(55);
		r.readInfo();
		
		// 2)
		Readable r2 = new Readable() {
			@Override
			public void readInfo() {
				System.out.println("r2 의 readInfo 입니다");
			}
		};
		r2.readInfo();
		
		// 3)
		Readable r3 = new Readable() {
			@Override
			public void readInfo() {
				System.out.println("r3 의 readfo 입니다");
			}
		};
		r3.readInfo();
		
		// 4)
		new Readable() {
			
			@Override
			public void readInfo() {
				System.out.println("따끈따끈한 readInfo");
			}
		}.readInfo();
		
		
		System.out.println();
		System.out.println("-- 추상클래스도 익명클래스 가능 --");
		Moveble m1 = new Moveble() {
			
			@Override
			public void move(int times) {
				System.out.println("move() " + times * speed);
			}
		};
		
		m1.move(2);
		m1.move(10);
		
		
		System.out.println();
		System.out.println("-- 일반클래스도 익명클래스 가능--");
		MyClass my1 = new MyClass();
		my1.aaa();
		my1.bbb();
		
		MyClass my2 = new MyClass() {
			@Override
			public void aaa() {
				System.out.println("my2의 AAA");
			}
		};
		my2.aaa();
		
		MyClass my3 =new MyClass() {
			// 오버라이딩 : Alt + Shift + S + V 
			@Override
			public void aaa() {
				System.out.println("my3의 AAA");
			}
		};
		my3.aaa();

	} // end main()

} // end class Anonymous01Main

// 추상 클래스
abstract class Moveble{
	int speed = 100;
	public abstract void move(int times);
}

// 일반 클래스
class MyClass{
	public void aaa() {
		System.out.println("aaa");
	}
	public void bbb() {
		System.out.println("bbb");
	}
}


** Person 클래스

package com.lec.java.inner07;

public class Person {

	// Person 외부 클래스의 멤버 변수
	private String name;
	
	// Person 외부 클래스의 생성자
	public Person(String name) {
		this.name = name;
	}
	
	
	public Readable createInstance(int age) {
		
		// 익명 내부 클래스:
		// 인스턴스 생성과 동시에 클래스가 정의됨.
		// new 인터페이스() { 익명 클래스 내부 작성 }; 
		// new 부모클래스() { 익명 클래스 내부 작성 };
		
		return new Readable() {
			@Override
			public void readInfo() {
				System.out.println("이름 : " + name);
				System.out.println("나이 : " + age);
			}
		};
	} // end createInstance
	
	
} // end class Person


// 인터페이스
interface Readable {
	public abstract void readInfo();
}


8) com.lec.java.inner08 패키지, Anonymous02Main 클래스

package com.lec.java.inner08;

public class Anonymous02Main {

	public static void main(String[] args) {
		System.out.println("익명 내부 클래스 활용");
		
		System.out.println();
		System.out.println("1. 익명클래스를 사용하지 않는 경우");
		
		Calculable tc1 = new TestMyMath();
		double result = tc1.operate(1, 2);
		System.out.println("result = " + result);
		
		
		System.out.println();
		System.out.println("2. 익명클래스를 사용하는 경우");
		
		// 1)
		Calculable tc2 = new Calculable() {
			
			@Override
			public double operate(double x, double y) {
				return Math.pow(x, y);
			}
		};
		System.out.println(tc2.operate(2, 4));
		
		// 2)
		result = new Calculable() {
			
			@Override
			public double operate(double x, double y) {
				return x * y;
			}
		}.operate(123, 3);
		System.out.println("result = " + result);
		
		// 3)
		System.out.println("result = " + new Calculable() {
			
			@Override
			public double operate(double x, double y) {
				return x % y;
			}
		}.operate(15, 4));
		
	} // end main()

} // end class Anonymous02Main


interface Calculable{
	public abstract double operate(double x, double y);
}

/*
  위와 같이 특정 추상 메소드만 implement 하는 목적으로 설계되는 인터페이스의 이름은
  보통 ~ able 로 작명 경우가 많다.  
  자바에서 제공하는 대표적으로 많이 사용하는 이러한 인터페이스들.
  Serializable, Cloneable, Readable, Appendable, Closeable,  
  AutoCloseable, Observable, Iterable, Comparable, Runnable,
  Callable, Repeatable, 
*/

class TestMyMath implements Calculable {

	@Override
	public double operate(double x, double y) {
		return x + y;
	}
}

 

9) com.lec.java.inner09 패키지, Anonymous09Main, Button 클래스

** Anonymous09Main

package com.lec.java.inner09;
/*
 * 리스너 (Listener)
 *   이벤트 중심의 프로그래밍 (웹, 앱, GUI 환경 등..) 에선
 *   특정 '객체' 에  특정 '이벤트' 가 발생하면 어떠한 '동작'을 수행하도록 프로그래밍 한다.
 *   
 *   함수형 프로그래밍이 아닌 자바에서는
 *   리스너는 내부클래스(익명클래스)로 제공합니다.
 *   
 */
public class Anonymous09Main {
	
	public static void main(String[] args) {
		System.out.println("익명 클래스 응용 : Listener");
		
		Button btnOk = new Button("OK");
		btnOk.actionClick();
		
		// 리스너 장착
		btnOk.setOnClickListener(new Button.OnClickListener() {
			
			@Override
			public void onClick() {
				System.out.println("딸깍딸깍");				
			}
		});
		
		btnOk.actionClick();
		
		
		btnOk.setOnDblClickListener(new Button.OnDblClickListener() {
			
			@Override
			public void onDblClick() {
				System.out.println("달그락 달그락 따닥");
			}
		});
		
		btnOk.actionDblClick();
		
		
		System.out.println("\n 프로그램 종료");
	} // end main()
	
} //end class

 

** Button 클래스

package com.lec.java.inner09;

public class Button {

	String name;
	
	public Button(String name) {
		this.name = name;
	}
	
	// 클릭시 수행하는 리스너  제공
	// 리스너 인터페이스 : OnClickListener
	//         - 를릭시 동작 메소드 : onClick();
	// 장착 메소드 : setOnClickListener
	//---------------------------------------------------
	// 리스너 인터페이스
	public static interface OnClickListener {
		void onClick();   // 클릭했을때 동작, 추상메소드
	}
	
	// 장착 리스너
	private OnClickListener clickListener = null; 
	
	// 리스너 장착 메소드
	public Button setOnClickListener(OnClickListener clickListener) {
		this.clickListener = clickListener;
		return this;
	}
	
	//----------------------------------------------
	public void actionClick() {
		System.out.println(name + " 버튼 클릭! (시스템 기본동작 수행)");
		
		if(clickListener != null)
			clickListener.onClick();  // 장착된 리스너 수행
		
	}
	
	
	// 더블클릭시 수행하는 리스너를  제공해보세요
	// 리스너 인터페이스 : OnDblClickListener
	//         - 더블를릭시 동작 메소드 : onDblClick();
	// 장착 메소드 : setOnDblClickListener
	
	//---------------------------------------------------
	// 리스너 인터페이스
	public static interface OnDblClickListener{
		void onDblClick();
	}
	
	// 장착 리스너
	private OnDblClickListener dblClickListener;  
	
	// 리스너 장착 메소드
	public Button setOnDblClickListener(OnDblClickListener dblClickListener) {
		this.dblClickListener = dblClickListener;
		return this;
	}
	
	//----------------------------------------------
	public void actionDblClick() {
		System.out.println(name + " 버튼 더블 클릭! 기본 시스템 동작");
		
		if(dblClickListener != null) {
			dblClickListener.onDblClick();  // 장착된 리스너 수행!
		}
		
	}
		
} // end class

'웹_프론트_백엔드 > JAVA프레임윅기반_풀스택' 카테고리의 다른 글

2020.03.31  (0) 2020.03.31
2020.03.30  (0) 2020.03.30
2020.03.26  (0) 2020.03.26
2020.03.25  (0) 2020.03.25
2020.03.24  (0) 2020.03.24