반응형

# Project

v01 -> gradle을 통한 경로파일 및 기초 셋팅하기 // $ gradle init (gradle 셋팅 시작) // $ gradle build (빌드 파일 생성)

          // $ gradle clean (build 폴더 삭제) // $ gradle compileJava (java 파일을 컴파일하여 build 폴더 안에 넣는다.)

          // build.gradle는 git에 올리지 않는다. // clean 과 compileJava로 인해 언제든 삭제, 생성할 수 있기 때문이다.

v02 -> 이클립스 사용을 위한 gradle 셋팅하기 // build.gradle 파일 안 plugins에 id eclipse 추가 후 $ gradle eclipse

          // gradle clean eclipse로 설정파일을 지울 수 있다.

          // tasks.withType(JavaCompile) { // build.gradle 파일 안에 별도 블럭으로 추가

          // options.encoding = 'UTF-8' //프로젝트의 소스 파일 인코딩을 gradle에게 알려준다.

          // sourceCompatibility = '1.8' // 소스 파일을 작성할 때 사용할 자바 버전

          // targetCompatibility = '1.8' } // 자바 클래스를 실행시킬 JVM의 최소 버전

v03 -> git 사용법 // $ git clone $ git add . $ git commit -m "-" $ git push

v04 -> 리터럴과 출력 // System.out.println("");

v05 -> 변수와 키보드 입력 // Scanner scan = new Scanner();   System.out.printf

v06 -> 배열과 흐름제어문 // int[] i = new int[size];   for (int i = 0; i < size; i++) {...}

v07 -> 클래스 -> 데이터 타입 정의 // class문 별도 분리(인스턴스 모아두는)

v08 -> 기본 문법의 활용 // do { switch(command) {case "커멘드1": ...} } while (조건);

v09 -> 기능 별 메서드 별도 분리 (메서드 추출) // 파일 내에서 메서드를 추출하여 분리함.

v10 -> 메서드를 별도의 클래스 파일로 분리 (클래스 추출) // 별도 파일을 생성하여 분리함.

v11 -> 패키지 -> 클래스 분류 package가 다른 클래스의 접근의 경우에는 public을 선언하여 접근 자격을 부여한다.

          // main에서 사용하는 keyboard 권한을 각 handler에게 넘겨주는 방법.

          // main에서 keyboard 선언, import를 한(keyboard 권한이 필요한) handler에 한해, main의 keyboard를 부여함

          // LessonHandler.keyboard = keyboard; 

          // handler에서는 main에서 넘겨준 키보드를 받기 위해서 public으로 handler의 키보드를 공개하여야 한다.

          // public static Scanner keyboard; // handler에서 선언

v12 -> 클래스 필드와 클래스 매서드의 한계 // ex) 게시판을 여러가지 만들때 클래스를 여러가지 만들어야 하는가 ?

          // 만약 1개의 파일에서 문제가 발생하면, 복사하여 만든 파일 모두를 수정해야하는 단점이 있음.

v13 -> 인스턴스 필드와 인스턴스 메서드의 필요성 // A obj = new A();(인스턴스는 new를 통해 heap 메모리로 접근)

          [class이름].a = 100; // static 필드는 (=클래스 필드) 클래스 소속이라 클래스 이름으로 접근이 가능하다.

          [new A()].b = 100; // non-static 필드(=인스턴스 필드) 인스턴스 소속이라 인스턴스주소로 접근이 가능하다.

          // 동일한 메서드를 사용 하는 게시판(클래스)를 여러개 생성하여야 할 때,

          // 클래스 메서드(스태틱 메서드)는 게시판을 관리할 핸들러를 각각 만들어줘야 한다. ex) 6게시판 6handler 파일

          // 인스턴스 메서드(논스태틱 메서드)는 게시판을 관리할 핸들러를 선언만 여러개 하면 된다. ex) 6게시판 6선언

v14 -> 생성자를 통한 초기 셋팅 하기 // 인스턴스 메서드 활용 

          // keyboard 객체를 따로 넘겨주고 new handler로 생성하지 말고, 생성자 파라미터를 keyboard 값을 넘겨주자.

v15 -> 게터 세터를 통한 인스턴스 변수 관리하기 // 다이렉트로 값 변경을 방지하기 위함.

          // 기존의 인스턴스를 private로, 타클래스에서 값을 주고(setter) 받을(getter) 메소드를 생성한다.

v16 -> UI 코드와 데이터 처리 코드를 분리하기 // 리펙토링

          // BoardList에는 Board라는 배열에 대한 데이터 값을 관리하는 내용의 메서드를 모아놓는다.

          // list 배열의 값을 늘려주고, 값을 실제로 넣는 add() 배열을 복사하여 리턴해주는 toArray()

          // 넘겨준 번호와 일치하는 배열을 찾아주는 get()까지 값을 다루는 메서드를 모아둔다.

          // BoardHandler에서는 실제 App에서 실행할 수 있는 즉 배열을 전체적으로 컨드롤 할 기능들을 모아둔다.

          // BoardList로부터 toArray()로 넘겨받은 값을 반복문을 통해 출력한다던지 listBoard()

          // 값을 직접 입력받아 데이터를 ListBoard에게 add()로 넘겨준다던지 addBoard()

          // 입력받은 번호를 get()으로 넘겨주어 리턴 받은 값을 출력해준다던지 detailBoard()

          // 값을 넘겨주거나, 받아서 처리해주는 Handler의 역할을 한다.

v17 -> 다형적 변수과 형변환

          // 기능은 같지만, 데이터의 형식에 따라 MemberList LessonList BoardList처럼 구분하여 사용하지 않고,

          // 다형적 변수를 이용하여, ArrayList 한개로 관리한다.

v18 -> 제네릭 문법의 방법과 이점 // Object는 모든걸 다 받지만, 제네릭 문법을 사용하면 정해진 애만 받을 수 있다.

          // 변수명은 E -> element  T -> type을 주로 사용한다.

v19_1 -> # ArrayList 클래스 정의 과정  CRUD(Create/Retrieve/Update/Delete) 기능 구현 // ArrayList 수정

- 1) 최소 클래스 정의
- 2) 객체 목록을 다룰 때 사용할 인스턴스 변수 준비
- 3) 인스턴스 변수 초기화를 생성자로 옮긴다.
- 4) 배열의 초기 크기를 설정할 수 있는 생성자를 추가한다.
- 5) 생성자에 있는 수퍼 클래스의 기본 생성자 호출 문장을 생략한다.
- 6) 배열의 기본 크기를 직접 지정하지 않고 상수로 정의한 후 그 상수를 사용한다.
- 7) 생성자에서 배열을 만들 때 초기 크기가 기본 크기 보다 작다면 기본 크기로 배열을 만든다.
- 8) 객체를 목록에 저장하는 add() 메서드를 정의한다.
- 9) 객체를 목록에서 꺼내는 get() 메서드를 정의한다.
- 10) 목록의 저장된 특정 위치의 값을 변경하는 set() 메서드를 정의한다.
- 11) 목록에 저장된 특정 위치의 값을 삭제하는 remove() 메서드를 정의한다.
- 12) add() 변경: 배열이 꽉 차면 50% 증가시킨다. 
- 13) get() 변경: 유효한 인덱스가 아니면 null을 리턴한다.
- 14) set() 변경: 유효한 인덱스가 아니면 메서드를 실행하지 않는다.
- 15) set() 변경: 변경한 후 변경 전의 값을 리턴한다.
- 16) remove() 변경: 유효한 인덱스가 아니면 메서드를 실행하지 않는다.
- 17) remove() 변경: 삭제한 후 삭제 전의 값을 리턴한다.
- 18) size 필드 값을 리턴할 size() 메서드를 정의한다.
- 19) remove() 변경: System.arraycopy()를 사용하여 삭제를 처리한다.
- 20) 목록에 저장된 객체를 배열로 리턴하는 toArray() 메서드를 정의한다.
- 21) toArray() 변경: Arrays.copyOf()를 사용하여 리턴할 배열을 만든다.
- 22) ArrayList에 제네릭(generic)을 적용한다.
- 23) 제네릭으로 지정된 타입의 배열을 리턴하는 toArray()를 추가한다.
- 24) toArray(E[] arr) 변경: 파라미터로 받은 배열이 넉넉하다면 새로 배열을 만들지 않고 그대로 사용한다.
- 25) 목록 중간에 값을 삽입하는 add(int,E) 메서드를 정의한다.
- 26) add()와 add(int,E)에 중복 작성된 배열을 늘리는 코드를 grow() 메서드로 분리한다.  
- 27) grow() 메서드에서 새 배열의 크기를 계산 코드를 newCapacity() 메서드로 분리한다. 

v19_2 -> BoardHandler 수정 // indexOfBoard 등등 넘겨받은 고유 값으로 index를 찾는 메서드 추가

            // index를 넘겨받지 않고, No(고유값)를 넘겨받아도 해당 값을 가진 index를 추출할 수 있음.

v19_3 -> Prompt 생성 // 문장을 출력하고 입력받는 것을 메소드로 처리한다.

            // return 받는 값을 indexOfBoard setNo 등등 입력받아야하는 메소드와 연계하여 보다 간결하게 처리 가능

v20 -> # LinkedList 만들기

- 1) 최소 클래스를 작성한다.
- 2) 값과 다음 값의 주소를 저장할 Node 클래스를 정의한다.
- 3) 링크드리스트의 첫 번째 노드와 마지막 노드의 주소, 크기를 저장할 인스턴스 필드를 선언한다.
- 4) add(Object) 추가
- 5) get(int) 추가
- 6) add(int, Object) 추가
- 7) remove(int) 추가
- 8) set(int,Object) 추가 
- 9) toArray() 추가
- 10) 제네릭 적용
- 11) toArray(E[]) 추가
- 12) size() 추가

v21 -> # Stack 만들기 // implements Cloneable

- 1) 최소 클래스를 작성한다.
- 2) 데이터를 저장할 레퍼런스 배열과 상수 필드를 준비한다.
- 3) 레퍼런스 배열을 초기화시키는 생성자를 만든다.
- 4) push() 추가
- 5) push() 변경 : 배열이 꽉찼을 때 배열의 크기를 증가시키는 코드를 추가한다.
- 6) push() 변경 : 배열 크기를 늘리는 코드를 별도의 메서드(grow())로 분리한다.(리펙토링)
- 7) grow() 변경 : 새 배열의 크기를 계산하는 코드를 별도의 메서드(newCapacity())로 분리한다.(리펙토링
- 8) pop() 추가 
- 9) empty() 추가
- 10) Object의 clone() 메서드 재정의 : shallow copy 
- 11) Object의 clone() 메서드 변경 : deep copy
- 12) 제네릭 적용

v22 -> # Queue 만들기 // shallow copy deep copy

- 1) 최소 클래스를 작성한다.
- 2) LinkedList를 상속 받는다.
- 3) offer() 추가
- 4) poll() 추가
- 5) Object의 clone() 메서드 정의 : shallow copy
- 6) Object의 clone() 메서드 재정의 : deep copy
- 7) 제네릭 적용

v23_1 -> 일반화(generalization) 1단계 // ArrayList와 LinkedList의 공통점 분리(슈퍼 클래스로)

            // ArrayList와 LinkedList에서 각 배열에 추가(add), 추출(get), 넣기(set), 제거(remove)하는 기능을

            // List라는 상위 클래스 파일에 파라미터까지 동일하게 새로 정의함.

            // List에 정의를 했다면, ArrayList와 LinkedList가 List를 상속하게 하고,

            // List에서 상속받는 기능들에 @Override 애노테이션을 부착하여 사용한다.

            // 단, ArrayList와 LinkedList의 각각 기능 구현이 두개가 다르기 때문에,

            // ArrayList와 LinkedList가 List의 기능을 가져와 오버라이딩 하는 형식

            // 하부 클래스가 먼저 만들어지고, 상위 클래스를 만들었으므로 generalization에 해당 된다.

v23_2 -> 일반화(generalization) 2단계 // 슈퍼 클래스를 추상 클래스로 정의하기.

             // generalization화 과정에 있어, 슈퍼 클래스를 일부로 추상 클래스로 정의한다.

             // 추상클래스는 public abstract class AbstractList<E> {} 과 같이 사용되며,

             // 추상클래스는 static이 들어갈 곳에 abstract를 넣고, 클래스명에도 Abstract를 붙혀 추상 클래스임을 밝힌다

             // 서브 클래스에서 정의하기 위해 만든 추상메서드의 경우에 public abstract void add(); 와 같이

             // 추상클래스는 static이 들어갈 곳에 abstract를 넣어 추상 클래스임을 밝히고

             // {} 내용을 정의하지 않고, 메소드명(파라미터); 로 ;를 붙혀 마무리 한다.

             // 추상 클래스로 정의하는 이유는, ArrayList, LinkedList에 맞게 하위 클래스에서 재정의하기 위해서이다.

             // 종합하면 상위 클래스 AbstractList에선 이러이러한 것들이

             // 하위 클래스인 ArrayList, LinkedList에 맞게 거기에서 재정의를 강요하기 위함이다.

v23_3 -> 일반화(generalization) 3단계 // 인터페이스 문법 사용

             // 추상 클래스에서 추상 메서드를 추출하여 인터페이스를 만든다.

             // 추상 클래스는 public abstract class AbstractList<E> implements List<E>와 같이

             // 23_2에서 만든 추상클래스 명에서 새로 만든 인터페이스를 구현한다는 의미에서

             // implements List<E>(인터페이스 클래스명)을 붙힌다.

             // 인터페이스는 public interface List<E> 와 같이 선언하며,

             // 인터페이스는 규칙이므로 항상 공개해야된다고 생각 // 메서드와 클래스명이 public으로 선언된다.

             // static이 들어갈 곳에 interface로, interface안에 들어갈 메서드의 경우에는 추상메서드와 같이 들어간다.

             // public abstract void add() // abstract void add() // public void add() // void add() // 다 가능

             // public abstract void add() 와 같이 들어가나, interface에서는 public과 abstract를 제외할 수 있다.

             // 즉 interface(List) 규칙을 따르는, AbstractList의 size()를 사용하는 ArrayList, LinkedList이 사용 가능하다.

             // 원래 interface의 규칙을 따르면 어떤 것이든 교체가 쉽게, 사용하기 위함을 목적으로 한다.

             // 따라서 Handler에서는 List의 규격을 통과한 어떠한 객체라도 사용이 가능하게 하며,

             // App에서 어떠한 기능을 사용할 지 객체(ArrayList, LinkedList)를 지정하여 사용하는 편리함을 가지고 있다.

v24_1 -> Iterator 디자인 패턴 적용 // ArrayList, LinkedList, Stack, Queue 모두 Iterator를 사용

             // 자료 구조와 상관 없이 값을 꺼내는 모든 방법에 Iterator 적용

             // Iterator의 기능은 다음 값이 있는지(hasNext(), 다음 값 출력하는 것(next())을 기능으로 한다.

             // Iterator를 별도 클래스 interface로 선언하여 구현한다.

             // 그 외 배열 전체를 출력한다던지(list) 등등은 별도 반복문, Iterator를 가지고 구현하면 된다.

             // List에서 다음값이 있는지 확인을 위해 현재 위치를 표시해야 한다. // cursor로 표시한다 // LinkedList 참조

             // ArrayList, LinkedList는 cursor가 list.size()보다 작다면 다음 값이 존재함 // 같으면 마지막 블럭이라는 뜻

             // Queue는 값을 출력한 후, 지워버리기 때문에 해당 배열의 사이즈가 0보다 크면 된다.

             // Stack은 미리 만들어둔 empty()의 명령어를 통해, !stack.empty()로 확인이 가능하다.

             // List(ArrayList, LinkedList)와 Queue Stack 각각 hasNext()와 next() 방식이 달라, 별도로 정의해줘야 한다.

             // List에 Iterator 적용하기로 했으면, Handler에서 List 내에 있는 Iterator를 새로운 iterator 래퍼런스로 호출

             // iterator.next()가 List 단일 객체를 리턴하기 때문에, 새로운 List 객체 레퍼런스를 생성해 받고, 반복문 출력

             // List의 경우, Abstract에서 Iterator()를 다루기 때문에, List배열 객체 안에는 Iterator가 들어 있다.

             // Stack과 Queue는 History 호출을 Iterator 하나로 통일한다.

             // 인스턴스 메서드로 Stack과 Queue의 객체를 넘겨 구분하면 된다.

v24_2 -> 스태틱 중첩 클래스(static nested class) // List, Stack, Queue Iterator를 nested class로 넣자.

            // nested class의 가장 중요한 점은. 해당 클래스를 특정 클래스만 사용할 때 넣는 것이다.

            // 다른 클래스에서도 사용한다면, 따로 클래스파일을 구분하는 것이 더 직관적이지만,

            // 한개의 클래스에서만 사용한다면 그 클래스파일 안에, 넣어주는 것이 더 직관적이고 유지보수하기 편하다.

            // static class ListIterator implements Iterator {...}

            // 해당 클래스에서만 사용하기 때문에, public으로 공개할 이유가 없다.

v24_3 -> 논 스태틱 중첩 클래스(non-static nested class) // 중첩클래스가 외부클래스의 인스턴스를 사용할때 선언

             // non-static nested class(=inner class)는 인스턴스의 주소가 없으면 사용할 수 없다(인스턴스 클래스라서)

             // 근데 자동적으로 외부 클래스에서 내장변수 this.를 inner클래스에 전달한다.

             // 논 스태틱 중첩 클래스는 인스턴스 클래스이기 때문에 당연히 내장변수 this를 가지고 있다.

             // 따라서 그냥 this라고만 적으면, 어떤 this를 가리키는지 모르기 때문에 

             // 외부클래스에서 받은 this를 가리킬때는 클래스명을 앞에 붙혀야 한다.

             // 즉, static nested class의 경우에는, return new QueueIterator<>(this);  // this를 파라미터로 넘기고,

             // public QueueIterator(Queue queue) { // 생성자 파라미터에 this를 받을, Queue를 선언해주고,

             // this.queue = queue.clone(); // 파라미터로 받은 외부클래스의 queue를 별도로 구분해줄 필요는 없다.

             // non-static nested class의 경우에는, return this.new QueueIterator<>(); // this의 주소를 넘기고(생략가능)

             // public QueueIterator() { // 생성자 파라미터로 this를 받을 주소를 별도로 넘길 필요가 없다.

             // this.queue = (Queue) Queue.this.clone(); // inner클래스의 this와 외부클래스 Queue의 this를 구분해준다.

v24_4 -> 로컬(중첩) 클래스 // 특정 메서드 안에서만 사용하는 중첩 클래스라면 로컬 클래스로 정의한다.

            // 클래스멤버로는(클래스 안에 선언되는 멤버) : 총 5가지가 있다.

        // 필드(static, non-static), 블록(static, non-static), 생성자, 메서드(static, non-static), 중첩클래스(static, non-static)

            // static 메서드 안에서, local class를 정의한다면 this를 사용할 수 없다. // staic 메서드는 this가 없다.

            // non-static 메서드 안에서, local class를 정의한다면 this를 사용할 수 있다.

            // 메서드 안에 중첩클래스를 선언하게 된다면, 이게 클래스 안에 중첩클래스로 선언한 것인지 헷갈릴 수 있다.

            // 따라서 간략하게 작성한 코드(pseudo;의사코드 = 가짜코드)를 통해 주석으로 알려준다.

v24_5 -> 익명 클래스(annoymous class) // 인스턴스를 하나만 생성할 거라면 익명 클래스로 선언한다.

            // 익명클래스는 이름이 없기 때문에 생성자를 만들 수 없다. // 생성자를 통해 원하는 값으로 셋팅이 불가능.

            // 따라서 인스턴스 블록을 사용하여, 인스턴스 필드를 초기화 시킨다.

            // 익명클래스는 정의하자마자, 래퍼런스를 생성하여 받아야 한다. // Iterator obj = new Iterator() {

            // 익명클래스는 수퍼클래스나 인터페이스의 이름을 가져온다.

            // class ListIterator<T> implements Iterator<T> { // return new Iterator<E>() { ... };

            // 익명클래스기 때문에 class와 class명 ListIterator과 implements를 날린다.

            // 익명클래스는 정의하자마자 래퍼런스를 생성하여 받기 때문에 new를 붙힌다. // 아니면 return에 박는다.

            // 슈퍼클래스나, 인터페이스의 생성자를 불러와야 되기 때문에 Iterator()를 호출한다.

            // 1번만 사용하기 때문에 <T>을 구분할 필요가 없다. // 즉 new Iterator<E>() { // 로 바뀌게 된다.

            // 익명클래스는 {}뒤에 ;를 붙혀야 한다. // 또한 굳이 레퍼런스로 익명클래스를 받지 않고,

            // return에 익명클래스를 바로 넣을 수 있다. // ;는 당연히 붙혀야 한다. // return 익명클래스{};

            // 해설하자면 수퍼클래스나, 인터페이스에 해당하는 객체를 하나만 만들고 싶다면, 

            // 굳이 클레스명을 부여하여 클래스를 따로 만들 필요 없이 익명 클레스로 처리한다.

v25 -> Java 컬렉션 API 사용하기 

 

반응형

+ Recent posts