본문 바로가기

학습 기록/JAVA

230817 싱글톤 패턴 singleton pattern , 열거형 enum , 제네릭generic

반응형

[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());

 

       }

}

 

 

반응형