[23.08.17] 18일차
<<진도>>
문제 풀이 (exception)
- 싱글톤 패턴
- enum 열거형
- generic 제네릭
<< 추후 진도 >>
[객체지향 프로그래밍] 고급
design pattern - singleton pattern
enum : 열거형
generic : 제너릭
collection framework : 컬렉션 프레임워크
inner class : 내부 클래스
lambda expression : 람다 표현식 / 람다 식
functional interface : 함수형 인터페이스
method reference : 메서드 참조
stream : 스트림
- ExceptionQuiz (*yd)
package exception;
public class ExceptionQuiz {
public static void main(String[] args) {
for(int i=1; i<11; i++) {
System.out.println(i);
try {
Thread.sleep(1000);// sleep(long millis) - milli s 1/1000초
}catch(InterruptedException e) { // interrupted 중단
System.out.println("예외 발생");
}
}
}
}
[풀이] ===================================================================
package exception;
public class ExceptionQuiz {
public static void main(String[] args) {
for(int i=1; i<11; i++) {
System.out.println(i);
// [예외 처리] 직접 처리 = try 구문
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
- ExceptionQuiz02 (*yd)
package exception;
import java.util.Scanner;
/*
* [예외 클래스 정의] ============================================
*
* 1) 사용자에게 이름을 입력 받고, 출력하시오.
* 2) inputName() 메서드에서 이름을 입력받으시오
* - inputName()메서드는 ExceptionQuiz02 class의 멤버 메서드
* - main()에서 inputName() 메서드 호출
*
* 3) !이름이 한 글자만 입력되면 NameLengthException예외 발생
* 4) 예외가 발생했을 때, 출력 문구 - class명 : 잘못된 이름 입력
* ===============================================================
*/
class NameLengthException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
public NameLengthException() {
super("잘못된 이름입력");
}
public NameLengthException(String name) {
super("잘못된 이름입력 " + name);
}
}
public class ExceptionQuiz02 {
public static void inputName() throws NameLengthException{
Scanner input = new Scanner(System.in);
System.out.print("이름을 입력하시오 (2글자 이상) : ");
String userName = input.next();
input.close();
if(userName.length() < 2) {
throw new NameLengthException(userName);
}
System.out.println("입력된 이름 : " + userName);
}
public static void main(String[] args) {
try {
inputName();
}catch(NameLengthException e) {
System.out.println(e.toString());
}
}
}
[풀이] ===================================================================
package exception;
import java.util.Scanner;
// 예외 클래스 정의
// 1) 사용자에게 이름을 입력 받고 출력하시오
// 2) inputName() 메서드에서 이름을 입력 받으시오
// - inputName() 메서드는 ExceptionQuiz02 class의 멤버 메서드
// - main() 메서드 내에서 inputName() 메서드 호출
// 3) 이름이 한 글자만 입력되면 NameLengthException 예외 발생
// 4) 예외가 발생했을 때, 출력 문구 - class명 : 잘못된 이름 입력
class NameLengthException extends Exception {
/**
*
*/
private static final long serialVersionUID = 2L;
public NameLengthException(String name) {
super("잘못된 이름 [" + name + "] 입력"); // 여기에 이름 넣은건 과제는 아니었는데 그냥 해보신다고 하면서 하셨음
}
}
public class ExceptionQuiz02 {
public static void inputName() throws NameLengthException {
Scanner input = new Scanner(System.in);
System.out.print("이름을 입력하시오(2글자 입력) >>> ");
String name = input.next();
input.close();
if (name.length()<2)
throw new NameLengthException(name);
System.out.println("입력된 이름 : " +name);
}
public static void main(String[] args) {
try {
inputName();
} catch (NameLengthException e){
System.out.println(e.toString());
}
}
}
- Ex01(pack.pattern)
package pattern;
/*
* [인스턴스 생성 불가능]
* - abstract class : 추상 클래스
* - interface : 인터페이스
* - private constructor: private 생성자
*/
class Cat {
private Cat() {}
}
public class Ex01 {
public static void main(String[] args) {
// Cat cat = new Cat();
}
}
- Ex02(pack.pattern)
package pattern;
class Dog {
int age = 5;
public void showAge() {
System.out.println("나이 : " + age);
}
public static void createInstance() {
Dog dog = new Dog();
dog.showAge();
}
}
public class Ex02 {
int num = 100;
public static void main(String[] args) {
Ex02 e = new Ex02(); // class를 type으로 인스턴스 생성가능
System.out.println("num : " + e.num);
Dog.createInstance(); //인스턴스 생성을 하는 메서드를 가진 class를 type으로 메서드호출 가능!
}
}
- Ex03(pack.pattern)
package pattern;
class Pattern {
// private static으로 field를 만들고 인스턴스 생성
private static Pattern member_field = new Pattern(); // static에 먼저 올려 접근가능
// 참조변수 member_field
// private 생성자 : 외부에서 객체생성 불가능하게 하려면 필수
private Pattern() {}
public static Pattern getPattern() { // 메서드를 통해 private인 member_field 메인에서 불러오기가능
System.out.println("[Pattern class 내] member_field >> " + member_field);
return member_field;
}
@Override
public String toString() { // member_field.toString() 주소대신 출력
return "Pattern 클래스입니다";
}
}
public class Ex03 {
public static void main(String[] args) {
// Pattern p = new Pattern();
// Pattern p2 = new Pattern();
// Pattern p = Pattern.member_field;
// System.out.println("p : " + p);
// Pattern.member_field = null; // 외부에서 필드에 접근이 안되게해야 함 private!
Pattern p = Pattern.getPattern();
System.out.println("p >> " + p);
Pattern p2 = Pattern.getPattern();
System.out.println("p2 >> " + p2);
// static에 저장된 하나의 주소를 이용하므로 모두 주소가 같다
// p == p2 == member_field
Pattern p3 = Pattern.getCount();
System.out.println("p3 >> " + p3);
}
}
- Ex01(pack.enumtype)
package enumtype;
import java.util.Scanner;
public class Ex01 {
public static void main(String[] args) {
System.out.println("1.월, 2.화, 3.수, 4.목, 5.금, 6.토, 7.일");
System.out.print("오늘의 요일을 선택하세요... ");
Scanner input = new Scanner(System.in);
int day = input.nextInt();
switch(day) {
case 1:
System.out.println("월) 주간 회의");
break;
case 2:
System.out.println("화) 프로젝트 기획 회의");
break;
case 3:
System.out.println("수) 진행 사항 보고");
break;
case 4:
System.out.println("목) 사내 축구 시합");
break;
case 5:
System.out.println("금) 프로젝트 마감");
break;
case 6:
System.out.println("토) 가족과 즐거운 시간");
break;
case 7:
System.out.println("일) 휴일입니다");
break;
}
input.close();
}
}
- Ex02(pack.enumtype)
package enumtype;
import java.util.Scanner;
interface Week {
// [interface_field] public static final
int MON = 1, TUE = 2, WED = 3, THU = 4, FRI = 5, SAT = 6, SUN = 7 ;
// 관련있는 상수들을 묶어서 관리
}
public class Ex02 {
public static void main(String[] args) {
System.out.println("1.월, 2.화, 3.수, 4.목, 5.금, 6.토, 7.일");
System.out.print("오늘의 요일을 선택하세요... ");
Scanner input = new Scanner(System.in);
int day = input.nextInt();
switch(day) {
// 원래 case 뒤에는 정수형 literal만 올수있음.
// final도 고정이 된 값 constant 상수이므로 올 수 있다.
case Week.MON: // 요일이 없어도 의미전달이 잘된다!
System.out.println("주간 회의");
break;
case Week.TUE:
System.out.println("프로젝트 기획 회의");
break;
case Week.WED:
System.out.println("진행 사항 보고");
break;
case Week.THU:
System.out.println("사내 축구 시합");
break;
case Week.FRI:
System.out.println("프로젝트 마감");
break;
case Week.SAT:
System.out.println("가족과 즐거운 시간");
break;
case Week.SUN:
System.out.println("휴일입니다");
break;
}
input.close();
}
}
- Ex03(pack.enumtype)
package enumtype;
class Season { // 상수를 관리하기 위한 class 이므로 외부에서는 객체를 생성할 필요X
public static final Season SPRING = new Season("봄");
public static final Season SUMMER = new Season("여름");
public static final Season FALL = new Season("가을");
public static final Season WINTER = new Season("겨울");
// field
private String name;
// private Season() {} // 외부에서 객체생성 못하게
private Season(String name) {
this.name = name;
}
@Override
public String toString() {
return this.name;
}
}
public class Ex03 {
public static void main(String[] args) {
// Season s = new Season(); // 생성불가 : 맞는 생성자 없음
System.out.println(Season.SPRING); // 1. 처음 주소 나옴
// 2. toString overriding하여 "봄"
System.out.println(Season.SUMMER);
// static에 할당되어 고정되는 주소 SPRING은 하나이다.
Season spring = Season.SPRING;
Season spring2 = Season.SPRING;
// => spring, spring2는 같은 객체다.
if(spring == spring2)
System.out.println("같다");
else
System.out.println("다르다");
// switch(spring) { // class를 가지고 만든 객체 type은 상수화는 했으나
// 리터럴은 아니므로 switch문 사용불가
// case Season.SPRING
// }
String s = "Hi";
switch(s) { // s는 문자열이 있는 주소라서 올 수 있다.
case "Hi":
System.out.println("Hi입니다.");
}
}
}
- Ex04(pack.enumtype)
package enumtype;
enum SeasonTwo { // 관련있는 상수들을 관리하기 위한 enum
SPRING, SUMMER, FALL, WINTER // 'enum' 에서는 마지막에 field가 올경우 ; 생략가능
}
public class Ex04 {
public static void main(String[] args) {
SeasonTwo spring = SeasonTwo.SPRING;
switch(spring) { // enum은 switch문에도 사용 가능
// 이미 enum type의 spring이 왔으므로 case에 올수 있는것은 enum SeasonTwo의 멤버들만 가능
case SPRING:
System.out.println("봄이다");
break;
case SUMMER:
System.out.println("여름이다");
break;
case FALL:
System.out.println("가을이다");
break;
case WINTER:
System.out.println("겨울이다");
break;
}
}
}
- Ex05(pack.enumtype)
package enumtype;
// ============================================
// [참조형] class, interface, enum
// ============================================
enum SeasonThree {
// [field] ====================================
// public static final => 상수(constant)
// : 값 변경 불가능
// : switch문에서 사용가능
// : enum에서는 반드시 상수가 가장 먼저 나와야한다
// ============================================
SPRING, SUMMER, FALL, WINTER;
// 참조변수명이 그대로 저장됨
// ex) SPRING ==
// public static final SeasonThree SPRING = new SeasonThree("SPRING");
// constructor
private SeasonThree() {} // 기본 private (외부에서 객체생성 불가)
}
public class Ex05 {
public static void main(String[] args) {
// SeasonThree s = new SeasonThree(); // enum 외부 객체 생성 불가
System.out.println(SeasonThree.SPRING);
System.out.println(SeasonThree.SUMMER);
System.out.println(SeasonThree.FALL);
System.out.println(SeasonThree.WINTER);
// enum에서 설정한 필드명 그대로 출력이 된다.
SeasonThree spring = SeasonThree.SPRING;
System.out.println("spring >> " + spring);
//toString()도 오버라이딩 되어있다
SeasonThree spring2 = SeasonThree.SPRING;
System.out.println("spring2 >> " + spring2);
// spring, spring2 주소가 같다
//================== ***enum에 있는 method들 *** =======================
// 열거형의 클래스명 리턴
System.out.println("참조변수 spring enum type >> " + spring.getDeclaringClass());
// .getDeclaringClass() : 해당 참조변수의 class명을 return
// 열거형의 상수값 리턴(field에 저장된 값)
System.out.println(spring.name());
// 열거형에 있는 상수를 배열로 리턴
System.out.println(spring.values()); // static통해 접근하라고함
System.out.println(SeasonThree.values()); // spring과 주소가다름
System.out.println(SeasonThree.values()[0]); // 배열 요소 출력
// .values() : 배열 형태로 출력
// 향상된 for문
System.out.println("<< 향상된 for문 >>");
for(SeasonThree s : SeasonThree.values()) {
System.out.println(s);
}
// 열거형 상수의 값
// SeasonThree.SPRING;
System.out.println("<< 열거형 상수 값 >>");
for(SeasonThree s : SeasonThree.values()) {
System.out.println(s.ordinal());//열거형 상수에 부여가 된 정수값
// 열거형의 왼쪽에서 부터 0 ~ 순서대로 번호가 부여됨
}
}
}
- Ex06(pack.enumtype)
package enumtype;
enum Number {
// ONE == public static final Number ONE = new Number("ONE");
ONE(1), TWO(2), THREE(3), FOUR(4);
private int num;
//constructor
private Number(int num) { // private 기본
this.num = num;
}
public int getNumber() {
return this.num;
}
}
public class Ex06 {
public static void main(String[] args) {
Number currentNumber = Number.ONE;
switch(currentNumber) {
case ONE:
System.out.println("1입니다");
break;
case TWO:
System.out.println("2입니다");
break;
case THREE:
System.out.println("3입니다");
break;
case FOUR:
System.out.println("4입니다");
break;
}
System.out.println(Number.ONE.getNumber());
// 서수 (순서) : 첫째, 둘째, ...
// 기수 (기본) : 하나, 둘, 셋, ... -> 기본 숫자, 양 quantity
System.out.println("<< 서수 출력 >>");
for(Number n: Number.values()) {
System.out.println(n.ordinal());
// System.out.println(n.getNumber());
//.ordinal(): 고유의 순서 0,1,2,3...
//.getNumber(): 생성자를 통해 만들어준 상수값
}
System.out.println("설정한 상수 값 출력");
System.out.println(Number.ONE.getNumber());
System.out.println(Number.TWO.getNumber());
System.out.println(Number.THREE.getNumber());
System.out.println(Number.FOUR.getNumber());
System.out.println("<< 향상된 for문 : 설정한 상수값 출력 >>");
for(Number n : Number.values()) {
System.out.println(n.getNumber());
}
}
}
- Ex07(pack.enumtype)
package enumtype;
enum Animal {
//public static final
DOG("해피"), CAT("누리", 5); // 상수마다 다른 생성자 호출형태
String name;
int age;
private Animal() {}
private Animal(String name) {
this.name = name;
}
private Animal(String name, int age) {
this.name = name;
this.age = age;
}
public void show() {
System.out.println("이름 : " + this.name);
System.out.println("나이 : " + this.age);
}
}
public class Ex07 {
public static void main(String[] args) {
Animal.DOG.show(); // 입력안된 age = 0;
Animal.CAT.show();
}
}
- Ex01(pack.generic)
package generic;
/*
* [Generic] 제네릭 =============================
* : type을 일반화(generalize) 하는 것
* : type은 컴파일 할떄 결정
* : generic은 type을 외부에서 결정(지정)
* : JDK 1.5부터 도입(지원)
* : 클래스뒤에 <> 로 표기
*
* ----------------------------------------------
* 타입 설명
* ----------------------------------------------
* <T> Type
* <E> Element
* <K> Key
* <V> Value
* <N> Number
* ----------------------------------------------
* ==============================================
*/
class Test<T> { // T : (type의 T) 타입변수, 타입 매개변수type parameter, generic parameter
// int대신 일반화의미 T(ype) 넣어줌 -> type이 결정이 안되어있고 -> 컴파일 시에 코드에 따라 달라짐.
private T element;
public T getElement() {
return element;
}
public void setElement(T element) {
this.element = element;
}
}
public class Ex01 {
public static void main(String[] args) {
Test<Integer> one = new Test<Integer>(); // int는 X 참조형만 넣어줄 수 있다!
one.setElement(5);
System.out.println(one.getElement());
Test<String> two = new Test<String>();
two.setElement("안녕"); // int형이라 setter 입력불가
// <= 2.5, "안녕" 등 다른 type을 받으려면 여러개 클래스 정의해야함 -> 비효율적
System.out.println(two.getElement());
}
}
'학습 기록 > JAVA' 카테고리의 다른 글
230821 콜렉션 Collection, 어레이리스트 ArrayList (0) | 2023.08.21 |
---|---|
230818 제네릭 generic (0) | 2023.08.18 |
230816 예외처리 Exception (0) | 2023.08.16 |
230814 추상클래스/메서드, 인터페이스 interface, 예외처리 exception handling (0) | 2023.08.14 |
230811 다형성, 추상 클래스(abstract class), 추상 메서드(abstract method), 인터페이스(interface) (1) | 2023.08.11 |