반응형

#블록의 종류

class Score {

    String name; // 필드 선언 public(접근범위) static(클래스소속) string name;

                    접근범위 public, defalut, protect, private  클래스 소속 static / 인스턴스 소속 default  string name;

    Score{ // 생성자 선언 public(접근범위) Score

    }        접근범위 public, defalut, protect, private

    void m() { // 메서드 선언 public(접근범위) static(클래스소속) void m()

    }            접근범위 public, defalut, protect, private  클래스 소속 static / 인스턴스 소속 default void m()

    static { //스태틱 블록 선언

    }

    { // 인스턴스 블록 선언

    }

}

 

#static method(= 클래스 메서드)

스테틱 메서드는 인스턴스 주소를 파라미터로 받는다. // 클래스명.메서드명(인스턴스주소);

public static void calculate(Score score) // 메서드 호출시 Score.calculate(s); 인스턴스 주소를 별도로 넘겨주어야 한다.

클래스 메서드는 모든 인스턴스에 대해 사용이 가능하다.

 

#non static method(= 인스턴스 메서드)

인스턴스 메서드는 내장 변수(built-in)가 있다. 이 변수의 이름은 this이다. // 인스턴스주소.메서드명();

public void calculate() // 인스턴스 메서드를 s.calculate();로 호출 할 수 있다.

단 인스턴스 주소를, 인스턴스 메서드 내 this.sum = this.kor + this.eng + this.math 등 this로 받는다.

인스턴스 변수를 보다 편하게 사용하기 위해서 인스턴스 메서드를 사용한다.

// 별도로 인스턴스 주소를 호출할때 메서드 명 앞에 알려주고, this로 주소를 받으므로 코드가 직관적으로 바뀐다.

 

#oop

#ex01

Exam0110 -> 클래스를 사용해야 하는 이유.

Exam0120 -> 클래스와 레퍼런스, 인스턴스

Exam0210 -> 여러개의 레퍼런스와 여러개의 인스턴스

Exam0220 -> 레퍼런스 배열 사용

Exam0310 -> 가비지 및 가비지 컬렉터 

Exam0320 -> 래퍼런스와 인스턴스의 역할 확인

Exam0410 -> 터미널 사용시 class(소스파일) 유무 확인을 해야하는 이유. // 이클립스 등 툴 사용 이유

                  // javac -encoding UTF-8 -d bin/main -sourcepath src/step03/Exam04_1.java

                  // 소스파일의 경로를 지정해줘야 실행이 가능한 경우 지정해줘야 한다.

Exam0420 -> 클래스의 사용 범위 // 클래스의 선언 위치에 따라 class 파일 생성도 다르다.

                   패키지 멤버 클래스 - A.class , 중첩 클래스(nested class) - Exam0420$B.class ,

                   로컬 클래스(local class) - Exam0420$1C.class(1C // 첫번째 로컬 C클래스라는 의미)

                   로컬 클래스는 해당 메서드 블록 안에서만 사용이 가능하다.

Exam0430 -> public 클래스와 non public 클래스 // public이 붙지 않으면 다른 패키지에서 사용 할 수 없다.

Exam0440 -> import의 역할 // *;(와일드카드)의 사용

Exam0450 -> *;(와일드 카드)의 역할 //

                  import com.eomcs.oop.ex01.test.*; 범용적으로 사용되는 클래스가 아니면, *;로 import 하지말자.

Exam0460 -> java.lang 패키지 // 가장 많이 사용되기 때문에 패키지 명을 명시하지 않아도 된다. 

                                           그 외 패키지는 꼭 패키지명을 명시해야 한다.

#ex02

Exam0110 -> 클래스의 용도 // 1. 사용자 정의 데이터 타입을 만들때(설계도) 2. 메서드를 묶을때(handler)

Exam0120 -> 스테틱 메서드

Exam0130 -> 인스턴스 메서드

Exam0210 -> 클래스의 용도 // 소스 코드를 관리하기 쉽게 관련된 기능을 묶을 때 사용

Exam0220 -> 클래스 변수를 내부적으로 보관 // 클래스 변수를 직접적으로 호출하여 사용

Exam0230 -> 클래스 변수(스태틱 변수)의 단점 // 두개의 식을 동시에 진행할 방법이 없다.

                  클래스가 메모리에 로딩되면 자동으로 Method Area 영역에 스태틱 변수가 생성된다.

Exam0240 -> 인스턴스 변수 // 인스턴스 변수는 개별적으로 관리하고 싶을때 선언한다.

                  인스턴스 변수는 new 명령을 사용하여 만들어 진다. new 명령시마다 heap 영역에 생성된다.

Exam0250 -> 인스턴스 메서드 // 인스턴스 메서드를 사용하여 파라미터에 별도로 인스턴스 주소를 전달할 필요가 없다.

 

#ex03

Exam0110 -> 레퍼런스와 인스턴스 변수 //(A obj = new A();)

                   Method Area에는 class 설계도(A)가

                   JVM stack에는 Main 메소드의 변수(args)와 레퍼런스(obj)

                   Heap에는 실제 설계도(A)로 만들어진 인스턴스 변수들이 있다.

Exam0120 -> 여러개의 레퍼런스 및 그에 맞는 인스턴스 변수 넣기

Exam0130 -> 스태틱 변수 // static 변수는 Method Area에 생성된다.(인스턴스 변수는 Heap에)

Exam0140 -> 스태틱 변수와 인스턴스 변수 // class A에 static int v1; int v2;

                  스태틱 변수는 A.v1으로 호출하여 사용 가능 // 스태틱 변수는 바로 생성

                  인스턴스 변수는 A p = new A(); p.v2 로 호출하여 사용 가능 // new를 통해 레퍼런스를 부여해야함.

Exam0150 -> 스태틱 변수(클래스변수)와 인스턴스 변수 표기법 // 스태틱 변수는 클래스 이름을 사용하여 접근해야함.

                  다른 개발자들이 인스턴스 변수라고 생각할 가능성이 있기 때문이다.

Exam0160 -> final 상수 표기하기

Exam0210 -> 클래스 메서드와 인스턴스 메서드 // 인스턴스 메서드는 레퍼런스 주소로 호출 한다.

Exam0220 -> 클래스 메서드 // 클래스 메서드는 클래스 이름으로 호출이 가능하다.

                  호출 할 메서드가 인스턴스 변수를 안쓰면 클래스 메서드로 사용하자.

Exam0230 -> 인스턴스 메서드와 인스턴스 변수

Exam0310 -> 인스턴스 메서드의 this 사용

                  this는 생략 가능하나, 로컬 변수와 인스턴스 변수가 이름이 같다면 로컬 변수를 가리킨다.

                  로컬변수가 아닌 인스턴스 변수를 가리키고 싶다면 this를 붙혀 구분을 해준다.

Exam0320 -> 인스턴스 변수가 로딩되는 영역 확인

Exam0410 -> 생성자 // 파라미터가 없는 생성자를 기본 생성자라고 한다.

                  // 생성자를 따로 만들지 않았더라도 컴파일러가 자동으로 생성한다.

                  생성자는 클래스 이름과 같아야 한다.

Exam0420 -> 생성자의 용도 // 보통 인스턴스 변수를 초기화 시키는 용도로 사용한다. (ex) 모니터 초기값 셋팅)

Exam0430 -> 여러가지의 생성자를 생성할 수 있다. // 생성자를 호출 인스턴스 생성 후, 따로 생성자를 호출할 수 없다.

Exam0440 -> 생성자의 호출 막기 // 생성자의 접근 범위를 private로 설정하여 인스턴스 생성을 막는다.

Exam0510 -> 변수 자동 초기화 // 클래스 변수와 인스턴스 변수는 자동 초기화 로컬 변수는 값을 넣어야만 사용 가능.

           정수(byte ,short, int, long, char) : 0 부동소수점(float, double) : 0.0 논리(boolean) : false 기타(String,Date) : null

Exam0520 -> 초기화 문장 // 변수 선언과 동시에 값을 저장한다. 변수 생성 즉시 할당 연산자가 실행된다.

Exam0530 -> 변수 초기화 및 생성자 // 변수 초기화 후, 생성자가 실행된다.

                  ex) class A에 int b = 200;을 주고 A() {b = 300;} 생성자를 생성해서 b값을 출력하면 300이 출력된다.

                  생성자를 주석처리하고 b값을 출력하면 200이 나온다. 즉 생성자보다 할당이 먼저 실행된다.

Exam0611 -> 인스턴스 블록(초기화 블록) // 아무 이름 없이 선언하는 블록 {}

Exam0612 -> 인스턴스 블록이 생성자 가장 윗 부분에 위치하게 된다.(그대로 복사)

Exam0613 -> 인스턴스 블록이 생성된 위치에 따라서, 가장 위에 선언된 인스턴스 블록부터 생성자 상단에 위치한다.

                   // 생성자가 인스턴스 블록보다 위에 위치해 있어도, 인스턴스 블록이 생성자 코드 위에 그대로 복사된다.

Exam0620 -> 인스턴스 블록은 생성자를 생성 할 수 없을 경우에 쓴다. // 익명 클래스의 경우 추후 더 자세히 다룸

Exam0631 -> 필드초기화 문장 실행 = 인스턴스 블록 실행, 생성자 실행 순서로 진행된다.

                  // 필드 초기화 문장과 인스턴스 블록은 먼저 선언된 문장이 생성자 상단에 위치한다.

Exam0632 -> 필드 선언 및 초기화 문장, 스태틱 블록, 인스턴스 블록, 기본 생성자, 생성자(파라미터순) 순서로 작성.

Exam0641 -> 스태틱 블록은 레퍼런스만 선언할 때는 실행되지 않는다.

Exam0642 -> 스태틱 블록은 클래스 맴버(필드(변수)나 메서드)를 최초로 사용할때 실행된다. // 변수에 값을 넣을 때

                  래퍼런스만 선언할때는 실행이 되지 않는 이유는 레퍼런스 선언만 놓고 봤을때  그 클래스를 사용한다고                    볼 수 없기에, 메모리 절약을 위해 실제로 실행하지 않는다.

Exam0643 -> 스태틱 블록은 클래스 맴버(필드(변수)나 메서드)를 최초로 사용할때 실행된다. // 메서드 

Exam0644 -> 스태틱 블록은 해당 클래스의 인스턴스를 최초로 로딩할때 실행된다.

                  // new A(); 로 레퍼런스가 아닌 '인스턴스'를 만들때이다.

Exam0645 -> 스태틱 블록은 자바에서 제공하는 도구를 사용해서 클래스를 최초 로딩할때 실행된다.

Exam0646 -> 스태틱 블록은 로딩이 이미 되어있다면 다시 로딩하지 않는다 // 다시 실행되지 않는다.

Exam0647 -> 클래스가 한번 로딩 되면, 2번째 실행 될때 스태틱 블록은 실행되지 않는다.

          2회차 // 필드 선언 및 초기화 문장 = 인스턴스 블록 실행, 생성자 실행

Exam0650 -> 그냥 넘어감

 

#ex03 test

#객체 간의 관계

1) 상속(Ingeritance)

Car ◁- Sadari / Truck (상속은 화살표를 세모를 사용함.)

class Truck extend Car {

}

2) 연관(Association) // 지속적인 사용

Car -> CarCenter 나 -> 친구(연관은 화살표를 사용함.)

class Car {

Carcenter cc;

}

3) 집합(Aggregation) // 포함하는 관계(느슨한 결합)

Car ◇-> BlackBox 나 ◇-> 안경 나 ◇-> 핸드폰 컴퓨터 ◇-> 키보드(집합은 빈 마름모 화살표를 사용함)

class Car {

BlackBox bb;

}

4) 합성(composition) // 포함하는 관계(강력한 결합)

Car ◆-> Engine 나 ◆-> 심장 컴퓨터 ◆-> CPU(합성은 찬 마름모 화살표를 사용함)

class Car {

Engine e;

}

#집합과 합성의 차이는 생명주기이다.(life cycle) container 같지않다 containee)

집합은 Car, 나, 컴퓨터가 사라져도 BlackBox, 안경, 핸드폰, 키보드는 다른데 사용이 가능하다 생각.

합성은 Car, 나, 컴퓨터가 사라지면 Engine, 심장, CPU가 같이 사라진다고 생각.

5) 의존(Dependency) // 특정 상황에서 사용

Car ······> 주유소 학생 ······> 강사 나 ······> 서점 (의존은 점점점 화살표로 사용함)

class Car {

void 주유(주유소) {

}

}

 

#ex04

Exam0111 -> String 인스턴스 초기화 // 문자열 리터털, char[](배열) byte[](바이트 문자 배열) 

Exam0112 -> 한글로 String 인스턴스 초기화 // 한글 출력이 깨진다. // OS마다 사용하는 문자 코드가 다르기 때문이다.

                  // String 클래스의 생성자 호출시 바이트 배열과 인코딩 정보를 함께 받는 생성자를 사용한다.

Exam0113 -> UTF-8 문자 코드로 String 인스턴스 초기화 // Window 콘솔창에서 한글이 깨지는 이유

Exam0120 -> Date() 기본 생성자 초기화 시키는 방법 // java.util.Date

Exam0130 -> 자바에서 생성자의 사용 권한을 막는 경우, 및 사용법 // java.util.Calender

                  생성자가 있다하더라도, 접근 권한이 없으면 호출 할 수 없다. // new명령을 통해 인스턴스 생성 불가

# Singleton(싱글톤) // 객체를 하나만 생성하게끔 강제하는 설계 기법

                  1. 생성자를 외부에서 호출하지 못하도록 private를 적용한다. 

                  2. 대신 객체를 생성해주는 메소드(getInstance())를 static으로 만든다.

Exam0210 -> String 클래스

                 인스턴스주소(s1).charAt(숫자) // 문자에서 숫자+1(배열이라고 생각) 번째를 출력한다.

                  ex) Hello 에서 charAt(1) 이면 e

                  s1.compareTo("문자") // 문자가 인스턴스주소보다 앞에 있으면 양수, 같으면 0, 적으면 음수

                  ex) Hello(인스턴스 주소)와 Helli는 6(양수), Hello와 Hello는 0, Hello와 Hellu는 -6(음수)

                  s1.contains("문자") // 인스턴스 주소에 "문자"가 들어있는지 확인

                  ex) Hello와 "ll"은 들어있으니 true, "ee"는 없으니 false

                  s2 = s1.concat("문자") // 새로운 인스턴스 주소에, 인스턴스주소+"문자"를 합쳐서 넣음.

                  ex) s2 = s1.concat(", World!")에서 s2 값은 Hello, World!

                  s1.equals("문자") // 인스턴스 주소와 "문자"가 같은지 비교

                  ex) "aaa" = false , Hello = "true"

                  s3.getBytes() // s3("ABC가각)에 들어있는 byte

                  String.format("%s님 반갑습니다", "홍길동"); // printf에 들어가는 f도 format이다.

                  String.join("문자", "홍길동", "임꺽정", "유관순");

                  // 가장 첫 "문자"를 ,"" 사이사이에 넣는다.

                  String.valueOf(true); // ()안의 값을 문자 값으로 바꿔준다. "" 붙어있어도 가능.

                  // String.valueOf(3.14f); String.valueOf(100);

Exam0220 -> Wrapper 클래스(Integer)

Integer i1 = Integer.valueOf(100); => 숫자 100을 i1 주소에 넣는다.

Integer x1 = Integer.valueOf("44"); => 문자 44를 10진수 숫자 44로 간주하여 x1주소에 넣는다.

Integer x2 = Integer.valueOf("44", 16); => 문자 44를 16진수 숫자 44로 간주하여 x2 주소에 넣는다.

Integer i1 = Integer.valueOf("문자"/숫자) // Integer 클래스로 문자/숫자를 Integer 주소에 넣는다.

int v2 = Integer.parseInt("문자") // Integer 클래스로 문자를 int 값으로 바꿀 수 있다.

int v1 = i2.intValue(); // Integer에 들어있는 "문자"/숫자를 int 값으로 바꿔준다.

                  int와 Integer의 차이 // Integer에는 null이 들어갈 수 있다.

                  Integer는 객체로, unboxing(Integer를 int로 바꿈)을 하지 않으면 산술 연산을 할 수 없다.

                  인스턴스 주소 값을 갖기 때문에 null이 들어갈 수 있는 것이다.

                  int i = integer.intValue(); // Integer를 int i로 바꾸는 방법(unboxing)

                  Integer integer = new Integer(i); // I를 Integer로 바꾸는 방법(boxing)

                  Integer i1 = Integer.valueOf(숫자); // 인스턴스 주소에 숫자를 넣음. 

                  i2.compareTo(i1) // i2가 i1보다 크면 1(양수), i1보다 작으면 -1(음수)

                  Integer.toBinaryString(숫자) // 숫자를 2진수로 변환

                  Integer.toOctalString(숫자) // 숫자를 8진수로 변환

                  Integer.toHexString(숫자) // 숫자를 16진수로 변환

                  float f = Float.parseFloat("3.14f"); // "문자"를 float으로 변환

                  boolean b = Boolean.parseBoolean("true"); "문자"를 boolean 값으로 변환

Exam0230 -> Math 클래스

                  ceil : 파라미터로 주어진 부동소수점 바로 위 정수값리턴(+값 쪽으로 올림) 

                  ex) Math.ceil(3.28) = 4 Math.ceil(-3.28) = -3

                  floor : 파라미터로 주어진 부동소수점 바로 아래 정수값리턴(-값 쪽으로 내림)

                  ex) Math.floor(3.28) = 3 Math.ceil(-3.28) = -4

                  pow : a의 b승의 값을 알고 싶을때

                  ex) Math.pow(a, b) // Math.pow(2, 7) = 128

                  round : 반올림)

                  ex) Math.round(3.14) = 3 Math.round(3.54) = 4

Exam0240 -> Date 클래스(작성일 2019.12.30)

                  getYear()  + 1900 = 2019 

                  getMonth() + 1 = 12

                  getDay() = 30

                  Date.parse(시간) // 1970 년 1 월 1 일 00:00:00 UTC 이후부터 시간까지의 밀리초 반환

                  System.currntTimeMillis(); // 1970 년 1 월 1 일 00:00:00 UTC 이후의 밀리 초 수를 반환

                  java.sql.Date today = new java.sql.Date(currMillis); // 생성자 사용, 현재 시간 today에 넣기

                  // java.sql.Date에 만들어진 (currMillis)를 파라미터로 받는 생성자를 new로 생성함.(초기값 셋팅)

                  String str = today.toString(); 

                  // toString이라는 인스턴스 메서드를 활용 // toString은 문자열 값으로 바꿔주는 애이다.

                  java.sql.Date d = java.sql.Date.valueOf("2018-03-21"); // 스태틱 메서드 활용

                  // new 명령이 아니고, valueOf라는 이름을 가진 스태틱 메서드에 넘겨준 파라미터로 값을 리턴받음.

Exam0250 -> Calendar 클래스 // Calendar c = Calendar.getInstance(); 

     c.get(1) or c.get(Calendar.YEAR)= 년도

c.get(2) + 1 or c.get(Calendar.MONTH) + 1 = 월(0~11) // 0~11까지 리턴하기 때문에 1을 더해줘야 한다.

     c.get(5) or c.get(Calendar.DATE)= 일 // 평일이 5일이니깐 기억하면 좋을듯.

     c.get(7) or c.get(Calendar.DAY_OF_WEEK) = 요일 // 1~7(일요일이 1 월요일이 2 토요일이 7)

     c.get(4) or c.get(Calendar.WEEK_OF_MONTH) = 그 달의 몇번째 주 // 달이 4주라고 생각

    c.get(10) or c.get(Calendar.HOUR) = 시(0~11)

    c.get(11) or c.get(Calendar.HOUR_OF_DAY) = 시(0~23)

    c.get(12) or c.get(Calendar.MINUTE) = 분

    c.get(13) or c.get(Calendar.SECOND) = 초

 

#ex05 

a -> 그냥 초기 버전

b -> 기존 a에 있는 파일을 손을 댄 버전.

      // 기존 클래스를 변경하는 것은 오류를 일으킬 수도, 돌아가던 코드가 안돌아갈 수도 등등 많은 리스크가 따른다. 

       this() // this생성자를 이용(생성자에서 다른 생성자를 호출)하여 파라미터 호출 생성자를 보다 쉽게 늘릴 수 있다.

       // 쓰지도 않는 코드가 누적되는 문제가 있다. // this생성자는 무조건 문장 첫 문장으로 와야한다.

c -> 기존 a에 있는 파일을 두고, a를 복사하여 기능을 추가한 버전(b와 결과는 똑같음)

       // 원본을 복사한 경우 원본에 만약 문제가 있다면 그 문제까지 같이 복사가 된다.

d -> 상속 // extends 클래스명 // public class Sedan extends com.eomcs.oop.ex05.a.Car { }

       // 상속에서 상속해 주는 클래스를 슈퍼클래스 상위클래스, 부모클래스, parents클래스라 한다.

       // 상속에서 상속을 받는 클래스를 서브클래스, 하위클래스, 자식클래스, child클래스라 한다.

       // 상속을 사용하는 목적은, 위의 b와 c의 단점을 보완하고, 코드의 재사용성을 높히기 위함이다.

       // 상속이란 기존의 코드를 손대지 않고 사용하는 기능이다.

e ->  new child 클래스를 하게 되면, parents 클래스 생성후 child 클래스를 생성한다.

       // child클래스의 필드 + parents 클래스의 필드

       // parents 클래스를 두번 이상 new로 생성한다면 parents 클래스에 있는 static 블록은 최초 한번만 실행된다.

       // 상속을 하게 되면 new 서브클래스명(); 으로 생성하면, 상위클래스의 필드까지 메모리에 생성된다.

f -> 자바의 모든 class는 Object의 자손이다. // 생략되었지만 모든 클레스에는 extends Object가 붙어있다.

      // C -▷ B - A 라고할 때, C c = new C();로 C의 생성자를 호출 할 때,

      // C는 B(슈퍼클래스)의 생성자를 호출하고, B는 A의 생성자를 호출하고 A는 Object의 생성자를 호출한다.

      // Object의 생성자를 실행 A로 리턴 - A의 남은 생성자를 실행 B로 리턴 - B의 남은 생성자를 실행 C로 리턴.

g -> 상속도 기본 생성자(super();)를 생성한다.

       // 기본 생성자를 변경(A(int value);)하면 하위클래스에서 상위클래스를 호출할때에도 super(100);으로 호출한다.

h -> 자바는 다중 상속이 불가능하다 // 같은 인스턴스와 메서드가 있을 때, 어떤 것을 만들어야될 지 모르기 때문

       // 문법이 복잡할 수록, 컴파일러도 복잡해지기 때문에 자바는 금지했다. c++은 가능

 

#ex06 a

Exam0111 -> 다형적 변수의 정의 // 상위클래스가 하위 클래스의 인스턴스를 가리킬 수 있음을 정의한다.

                // 하위 클래스는 상위클래스의 인스턴스 맴버를 가지고 있기 떄문이다.

                // Sedan s는 new Sedan()을 실행할때, Car의 생성자를 호출하고, Car는 Vehicle의 생성자를 호출한다.

                // 따라서 Sedan s는 Car의 생성자, Vehicle의 생성자를 호출하여 상위 클래스의 인스턴스 맴버를 가진다.

Exam0112 -> 레퍼런스의 메모리 주소 확인

Exam0113 -> 같은 상위클래스를 두고 있는 하위클래스 // 부모가 같아서 다른 형제의 인스턴스는 사용 못함.

Exam0114 -> 하위 클래스는 상위 클래스의 인스턴스를 가지고 있다. 

                  // 따라서 하위 클래스의 메모리 주소 값을 상위클래스가 사용할 수 있다.

Exam0115 -> 상위 클래스가 하위 클래스를 사용하는 방법. // Vehicle v1 = new Sedan();

                  // v1.cc = 1980; v1.value = 16; v1.sunroof = true; // 다 컴파일 오류

                  // 상위 클래스 주소 v1은 new Sedan()이라 하더라도 Vehicle의 주소를 가리키기 때문에

                  // 하위 클래스 Car와 그 하위 클래스 Sedan의 인스턴스를 사용할 수 없다.

                  // Car와 Sedan의 인스턴스를 메모리에 가지고는 있으나,

                  // Vehicle까지밖에 접근권한이 없다고 생각하자.

                  ((Sedan)c).sunroof = true; ((Sedan)c).auto = true;

                  // c는 new Sedan()이므로 Sedan으로 명시적 형변환 후, Sedan 인스턴스 사용 가능

                  Sedan s = (Sedan)c; s.sunroof = ture; s.auto = true;

                  // 또는 아예 Sedan s라는 새로운 래퍼런스를 만들어 c를 형변환해서 사용가능

Exam0116 -> 형변환의 오류 // 컴파일러는 속일 수 있으나, 실행하면 오류 발생함.

                  // Car c = new Car(); Sedan s = (Sedan)c; s.sunroof = true; s.auto = true;

                  // 0115와의 차이점은 Car 레퍼런스 c를 0115는 new Sedan()으로 선언했고,

                  // 0116은 Car레퍼런스 c를 new Car()로 선언했다.

Exam0210 -> 상위 클래스가 하위 클래스를 사용하는 방법. // Exam0115 내용과 같음.

Exam0310 -> 형변환 오류 // Exam0116 내용과 같음.

Exam0411 -> 코드가 같더라도, 파라미터로 받는 형식이 다르면 실행되지 않는다 // 오류

Exam0412 -> 코드가 같더라도, 파라미터의 형식이 다르면 여러개의 코드를 만들어야 되는 불편함이 존재한다.

Exam0413 -> 다형적 변수의 필요 이유 // 동일한 코드의 메서드를 서로 다른 레퍼런스로 인해 여러개 만들지 않기 위함.

                  // Sedan과 Truck의 정보 출력 메서드 코드가 동일함에도, Sedan과 Truck의 메서드를 별도로 만들어야 함

                  // 따라서 Sedan과 Truck의 공통적인 상위 클래스를 래퍼런스로 받아 하나로 통합할 수 있음.

                  // 상위클래스는 두 클래스를 공통적으로 가리킬 수 있기 때문이다.

Exam0511 -> instanceof 사용법 // Vehicle v = new Sedan();

                  // 레퍼런스에 들어있는 주소가 특정 클래스의 인스턴스인지 확인을 한다.

                  // 즉 조상인지 확인을 한다고 생각.

                  // v instanceof Sedan // boolean 값 리턴

                  // Sedan Car Vehicle Object -> true   Truck -> false

Exam0512 -> getClass 사용법 // Vehicle v = new Sedan();

                  // 레퍼런스가 가리키는 인스턴스의 실제 클래스 정보를 리턴한다.

                  // v.getClass() == Sedan.class // boolean 값 리턴

                  // Sedan -> true   Car Vehicle Truck -> false   Object -> 오류

Exam0521 -> instanceof 사용법 2

 

#ex06 b

Exam0111 -> 오버로딩 적용 전

Exam0112 -> 오버로딩(overloading)이란 ? // 같은 이름의 메서드를 넘겨주는 파라미터의 구분, 여러개를 만드는 방법

               // C언어의 경우 int+int, float+float 같이 같은 더하기를 실행하는 메서드라도 이름이 같으면 안된다.

               // 따라서 C언어는 int+int는 plutint, float+float은 plutfloat 등 이름을 구분해서 사용해야 한다.

               // 그러나 자바는 넘겨주는 파라미터를 구분하여 plus(int + int) plus(float + float)으로 구분할 수 있다.

Exam0210 -> 오버로딩 사용 법

Exam0220 -> 상속 클래스의 오버로딩 호출 

                  // 오버라이딩은 부모클래스에 있는 메소드를 자식클래스에서 재정의를 하는거고

                  // 오버로딩은 같은 이름의 메소드를 여러개 만드는 것이다.

                  // 슈퍼클래스, 일반클래스 구분하지 않고 이미 있던 메소드를 파라미터만 다르게 추가하면 오버로딩

Exam0310 -> 오버로딩의 정의

                  // 파라미터와 파라미터의 타입이 다르더라도, 동일한 기능을 발생하는 메소드의 이름을 같게 하는 것

 

#ex06 c

Exam0110 -> 오버라이딩 적용 전

Exam0120 -> 오버라이딩 적용 전 // A클래스를 손대기도 어렵고 복사해서 사용한다면, A2라는 이름을 기억해야한다.

Exam0130 -> 오버라이딩 // 부모클래스에 있는 메소드를 자식클래스에서 재정의하여 사용함. 덮어쓰기.

Exam0210 -> 오버라이딩 했다고 착각하는 오버로딩(파라미터 착각)

Exam0220 ->@Override // 0210의 문제를 확인하는 방법 // 애노테이션

                 // 메서드 정의 앞에 @Override를 붙힌다.

                 // @Override를 붙혔을때 에러 뜨는건 오버라이딩이 제대로 된게 아니다.

Exam0310 -> private void m1() {}// 접근 범위 : 현재 클래스에서만 접근 가능

                  void m2() {} // (default) 접근 범위 : 현재 클래스 + 같은 패키지 소속 클래스

                  protect void m3() {} // 접근 범위 : 현재 클래스 + 같은 패키지 소속 클래스 + 자식 클래스

                  public void m4() {} // 접근 범위 : 모두

#Override 오버라이딩 // 접근 권한이 없는 메서드는 오버라이딩 할 수 없다.

// 오버라이딩 메서드의 접근 범위를 확대하는 것은 되나, 반대로 축소하는 것은 불가능하다.

// private -> default -> protect -> public // 오버라이딩 시 왼쪽에서 오른쪽으로 변화하는 것은 가능.

Exam0410 -> this.m()으로 메서드를 호출하면 현재 클래스부터 최상위 슈퍼클래스까지 올라가면서 메서드를 찾는다.

                  super.()로 메서드를 호출하면 슈퍼클래스부터 최상위 슈퍼클래스까지 올라가면서 메서드를 찾는다.

Exam0420 -> 0410을 보여줌.

 

#ex06 d

Exam01 -> A a3 = new A2() // a3.m()을 하면 A의 m()을 호출하지않고, A2의 m()을 호출한다 // 오버라이딩

               // A2의 설계도로 만들어진 a3는, A의 주소를 가지고 있지만 A2가 A를 상속받은 하위 클래스이기 때문에 

               // A2의 m()을 호출할 수 있다. 다만 a3.x()는 불가능하다. // A가 가지고 있던 메소드가 아니기 때문.

Exam02 -> 다형적 변수와 오버라이딩 // 메소드를 찾을때 항상 바로 상위 클래스에서 찾는다.

                // 현 클래스에 메소드가 없다고 가장 상위 클래스로 올라가는 것이 아니다.

 

#ex06 e

Exam0110 -> final class 서브 클래스// final로 선언된 클래스는 서브클래스를 만들 수 없다.

Exam0120 -> final class 상속 //  final로 선언된 클래스를 상속받을 수는 없다.

Exam0130 -> final 메서드 오버라이딩 // final로 선언된 메서드는 오버라이딩 할 수 없다.

Exam0140 -> final 메서드 상속

                  // final이 붙지 않은 클래스를 상속받아도, 그 안의 final로 선언된 메서드를 오버라이딩 할 수 없다.

                  // 그 외 final이 붙지 않은 메서드를 오버라이딩 하는 것은 가능하다.

Exam0210 -> final 상수 // final이 붙은 상수는 한번 선언되면 값을 변경할 수 없다.

Exam0220 -> final 상수 // 보통 final 상수는 static 으로 관리한다.

Exam0310 -> final 상수 // 변수 선언시 굳이 값을 주지 않아도 된다. // 단 값을 부여하면 이후 값 변경 불가.

Exam0320 -> final 파라미터 // 파라미터로 넘겨주는 값을 수정하면, 그 값을 다시 사용 못하기 때문에

                  // 실무에서는 파라미터의 값을 final로 선언하는 경우가 많다.

 

#ex07 a

Exam0110 -> 캡슐화(encapsulation) 사용 전

Exam0111 -> 캡슐화 필요 이유 // 임의로 값을 부여하여 값을 변경할 수 있다.

Exam0210 -> getter의 사용 이유 // 직접 값을 넣는 필드가 아닌 경우에 private으로 설정하여 접근을 막는다.

                  // private로 설정하여 접근이 불가능 함으로, getter를 만들어 값을 리턴 받는다.

Exam0211 -> setter의 필요 이유 // 기존의 값을 변경하고, 메서드를 호출하지 않으면 값을 부여받지 않는,

                  // getter값의 경우에 변경되지 않기 때문이다.

Exam0310 -> setter 사용 // setter에 해당 값이 변경될 때 적용되는 메서드를 호출하여, 변경을 즉각적으로 반영한다.

Exam0311 -> 필드(field)와 프로퍼티(property) // 필드는 getter/setter 생성을 필요로 하는 인스턴스 변수를 말함.

                  // 필드는 굳이 게터 세터가 필요 없더라도, 외부 접근을 차단하기 위해 사용한다.

                  // 프로퍼티는 정확하게 말하면 getter와 setter를 얘기한다. 

                  // 프로퍼티는, 필드를 외부와 연결해주는 것을 말하기 때문에 getter와 setter가 프로퍼티이다.

#ex07 b 

Exam0110 -> 캡슐화(encapsulation) 사용 전 

                  // private : 클래스 내부에서만 접근 가능

                  // (default) : 클래스 내부 + 같은 패키지

                  // protected : 클래스 내부 + 같은 패키지 + 자식클래스

                  // public : 모두 접근 가능!

Exam0120 -> 접근 범위 확인 // private로 막은 경우에는 클래스 외부에서 접근 불가능하다.

Exam0130 -> getter setter를 통한 접근 

Exam0140 -> 잘못된 값을 setter로 부여 할 수 있다.

Exam0210 -> 접근 범위에 대한 테스트 

                   // A는 같은 패키지에 속해 있기 때문에 default protect public 모두 생성이 가능하다.

                   // B는 같은 패키지에 속해있지 않고, 자식클래스가 아니므로 public 만 생성이 가능하다.

                   // C는 같은 패키지에 속해있지 않고, 자식클래스는 맞으나, 자신의 인스턴스 변수가 아니다.

                   // 이 의미는 C로 생성했는데 지금 접근하는 클래스는 Exam0210으로, C로 생성했기 때문에 접근 불가.

                   // C를 상속받은 Exam0210으로 생성했다면 protect를 사용할 수 있다.

                   // private는 당연히 접근 불가, default는 같은 패키지가 아니라서 당연히 접근 불가

                   // protected는 Exam0210에서 C로 생성하였기 때문에 Exam0210에서 사용이 불가능하다.

                   // Exam0210은 같은 패키지에 속해있지 않고 (C를 상속받았으니)

                   // 자식클래스가 맞고 C의 하위 클래스라 자신의 인스턴스 변수가 맞다.

Exam0220 -> 생성자를 private로 생성 // 생성자를 private으로 만드는 이유는 초보때는 없다.

                  // 인스턴스 생성과정이 복잡할 경우에 사용하는데, 메서드를 통해 복잡한 셋팅을 다 하기 위함이다.

Exam0230 -> Calender // 생성자를 protected로 막아놓은 대표적인 예

                  // Calendar.getInstance(); // Calender 내부에서 public으로 선언된 메서드로 호출을 한다.

 

#ex08 a

Exam01 -> 특수화/전문화(specialization)와 일반화/표준화(generalization)

 

#ex08 b

Exam01 -> 일반화/표준화(generalization) // 서브클래스를 먼저 만들고 서로 중복된 기능을 묶는다.

                // 실제로 새로 만든 클래스는 사용하지 않는다. 단지 서브클래스에게 공통 기능을 상속한다.

                public Car() {
                    super();
                  }

 

#ex08 c

Exam01 -> 추상클래스 // 일반화/표준화(generalization) 클래스를 abstract로 선언하여 추상클래스로 사용하자.

               // public abstract class Car {}

               // 추상클래스는 인스턴스를 생성할 수 없다.

 

#ex08 d

Exam01 -> 추상메서드 // 무조건 서브클래스에서 재정의 되어야하는 메서드인 경우 서브클래스에 정의 하는 문법

                public abstract void run(); // 얘는 {}를 붙히지 않는다.

                // 추상메서드를 갖는 클래스는 반드시 추상클래스여야만 한다.

 

#ex08 test

A -> class 종류와 특성 정리

B -> 인스턴트 및 메서드 종류와 특성 정리

C -> 스태틱 멤버과 인스턴스 멤버 종류와 특성 정리

D -> 상속과 하위클래스의 인스턴스 특성 정리

E -> 생성자 오버로딩 특성 정리

F -> 다형적 변수 특성 정리 

G -> 오버라이딩(Override)과 오버로딩(Overload) 특성 정리

H -> 접근 범위에 따른 특성 정리

I -> 캡슐화 특성 정리 // getter setter

J2 -> J를 Generalization 함

J3 -> 추상클래스 (abstract class)

J4 -> 추상클래스의 의미 // 하위 클래스에 구현을 미룬다.

 

#ex09 a

before -> 인터페이스 사용 전

after -> 인터페이스 사용 후 // 인터페이스 사용 목적 및 규칙

           // 인터페이스 레퍼런스 선언 참고. (after - Exam01)

 

#ex09 b

Exam01 -> interface의 규칙 // 인터페이스는 인스턴스를 사용할 수 없다. // A4 obj = new A4(); // 불가능

Exam02 -> interface의 규칙 // 굳이 적지 않아도, public이며, static이고, final이다. 또한 내용을 구현하면 안된다. 

 

#ex09 c

Exam01 -> 레퍼런스 타입에 따른 메서드 호출 범위 // 클래스 타입 레퍼런스 , 인터페이스 타입 레퍼런스

               // 클래스 타입 레퍼런스인 obj는 클래스 내 모든 메서드를 호출할 수 있다.

               // 인터페이스 타입 obj2는 해당 인터페이스 내 메서드와, 상속받은 인터페이스의 메서드를 호출 할 수 있다.

               // 인터페이스 타입 obj3는 해당 인터페이스 내 메서드를 호출 할 수 있다.

Exam02 -> 여러개의 인터페이스의 규칙시, 객체에 따른 메서드 사용법 // 레퍼런스 범위 설정 후 사용하면 된다.

               // 범위를 벗어난 메서드는 당연히 사용할 수 없다.

               // B를 상속받았더라도, B가 A를 상속받았기 때문에 A의 메서드도 구현하여야 한다.

Exam03 -> 인터페이스간 메서드 명이 겹쳐도 상관이 없다. // 메서드를 B와 D에서 공유할 수 있다.

Exam04 -> 인터페이스간 메서드 명이 같을때 불가능한 경우 // Exam03의 예외

               // 인터페이스 메서드 명이 같을때,

               // 파라미터 형식이 다른 메서드는 정의가 얼마든지 가능하다. (Overload 오버로딩)

               // 단, 리턴타입이 다른 경우에는 불가능 하다.

 

#ex09 d

Exam01 -> ex09 c의 내용과 같다.

 

#ex09 e // default 메서드

인터페이스에 새로운 기능을 추가하는 방법 

방법 1) 새로운 인터페이스(Computer2)를 만들어 기존의 인터페이스(Computer)를 상속받아,

          해당 클래스(NewComputer1)가 새로운 인터페이스를 따르게 하면 된다.

=> 규칙에 따라 구분하도록 코딩해야 하기 때문에 프로그래밍 하기가 불편

     // Computer2라는 것을 새로 만들어 그 이후 버전의 컴퓨터는 Computer2 인터페이스를 따르도록 하는 방법.

     // 추후 규칙이 늘어난다면, Computer3, Computer4, ... 늘어나서 관리하기 복잡하며 어려움이 있다.

방법 2) 기존 인터페이스(Computer)에 default 메서드를 추가한다.

          이미 구현된 메서드이기 때문에, 기존 (First, Second, Third Com)메서드 오류가 발생하지 않는다.

=> 인터페이스의 메서드는 원래 추상 메서드이기 때문에, 하위 클래스에서 재정의 하여야 한다.

     default 메서드는 이미 구현이 된 메서드이기 때문에 하위 클래스에서 강제로 재정의하게 할 수 없다는 단점이 있다.

     // Computer에 새로 추가할 규칙을 default 메서드를 이용하여 정의를 해버리는 방법.

     // 따라서 기존에 Computer를 상속 받던 First, Second, Third에서 오류가 일어나지 않는다.

     // 규칙을 따라야하는 컴퓨터에서만 재정의를 하면 된다.

     // 단, 재정의를 강제하지 않기 때문에

     // 재정의를 강요하는 인터페이스, 추상클래스의 의미에 반하는 오류를 가지고 있다.

 

#ex09 f

Exam01 -> 인터페이스 직접 구현

Exam02 -> 인터페이스를 구현한 클래스를 상속 받는다.

Exam03 -> 인터페이스 간접 구현

             // 상위클래스에서 인터페이스를 구현했다면, 하위 클래스에서 또 인터페이스를 구현할 필요가 없다.

 

#ex09 g

Exam0110 -> 인터페이스의 추상 메서드는 반드시 구현해야 한다.

Exam0120 -> default 메서드 // default로 선언된 메서드는 구현하지 않아도 컴파일 오류가 발생하지 않는다.

Exam0130 -> 인터페이스도 static 메서드를 가질 수 있다.

                  // 인터페이스의 스태틱 메서드는, 인터페이스명.메서드명으로 호출한다. // A.m3()

 

#ex10 a

Exam01 -> 추상 클래스는 인스턴스를 생성 할 수 없다.

Exam02 -> 추상클래스를 상속받아, 상속받은 추상클래스의 추상메서드를 구현하지 않는다면

               // 에러가 뜬다 // 즉 추상클래스(abstract)로 선언해야한다.

Exam03 -> 일반 클래스(concrete class)는 추상 메서드를 가질 수 없다.

               // 즉 추상클래스를 상속받아 추상메서드를 구현했다면 일반 클래스로 선언할 수 있다.

               // 추상 클래스(abstract class)는 일반 변수& 일반 메서드와 추상메서드를 가질 수 있다.

 

#ex10 b

Exam01 -> 인터페이스를 구현한다는 것은 모든 메서드를 구현한다는 것이다.

Exam02 -> 하나라도 구현하지 않는다면 에러가 뜬다.

Exam03 -> 추상클래스를 상속받아 원하는 부분의 인터페이스를 구현한다 

               // 미리 인터페이스의 몇몇 메서드를 구현한 추상클래스를 상속받는다.

 

#ex10 c

Exam01 -> 템플릿 메서드 패턴 // 수퍼클래스에서 추상적으로 표현하고 서브클래스에서 구현하는 방식.

 

#ex11 a

Exam0110 -> 스태틱 클래스에서 스태틱 멤버와 인스턴스 멤버 호출 방법과 한계

Exam0120 -> 같은 클래스의 스태틱 맴버를 스태틱 메서드와 인스턴스 매서드는 둘 다 호출할 수 있다.

Exam0130 -> 다른 클래스의 스태틱 멤버를 호출하는 방법. // 클래스명으로 호출한다.

Exam0140 -> import static 문법 사용 // import로 static클래스를 선언하면, 메서드,인스턴스 명으로 호출이 가능하다.

                  // 단 static nested class는, import시 static을 붙히지 않는다.

Exam0210 -> 논스태틱 클래스에서 스태틱 멤버와 인스턴스 멤버 호출 방법과 한계 // 바깥클래스명.this

Exam0211 -> non-static class에서 inner class와 바깥 클래스의 인스턴스의 이름이 같을 때 호출 방법 // this는 inner

Exam0220 -> 같은 클래스의 인스턴스 멤버는 인스턴스 매서드에서만 사용할 수 있다. // 스태틱 메서드에선 불가능

Exam0230 -> 다른 클래스의 인스턴스 멤버는 인스턴스주소로만 사용할 수 있다. // 레퍼런스 생성 후 레퍼런스로 호출

Exam0231 -> inner class 의 생성자가 자동으로 변한다. // obj.new A("홍길동"20);

                  // new A(obj, "홍길동", 20); 로 바뀐다. 즉 obj라는 주소의 값이 생성자에 들어간다.

Exam0240 -> 중첩클래스 응용 // non-static nested class // play()를 호출하려면 player 객체가 이미 있어야 하며,

                   // player 객체가 있으려면 Musics 객체가 먼저 존재하여야 한다.

Exam0241 -> player를 만든 musics 객체를 사용하려면 // "바깥_클래스명.this"을 사용한다.

Exma0242 -> 딱히 할말 없음

Exam0310 -> 로컬 클래스의 한계

                  // 로컬 클래스는 로컬 변수와 같이 그 클래스가 정의되어있는 클래스 안에서만 사용이 가능하다.

Exam0320 -> 로컬 클래스의 컴파일 명 // [바깥 클래스명][$번호][로컬 클래스명].class

                  // class A { // 예) Exam0320$1A.class // class A { // 예) Exam0320$2A.class

                  // 위 $1A와 $2A의 차이는 해당 Exam0320안에 선언된 A의 순서이다. 

                  // 로컬 클래스이기 때문에, 해당 로컬 영역을 벗어나면 같은 이름을 선언할 수 있다. // int i 생각

Exam0330 -> 스태틱 클래스 안에 정의된 로컬 클래스에서는 바깥(스태틱) 클래스의 this를 사용할 수 없다

                  // 당연히 static 클래스기 때문에 this를 가지고 있지 않기 때문이다.

Exam0340 -> 인스턴스 클래스 안에 정의된 로컬 클래스에서는 바깥(인스턴스) 클래스가 this를 가지고 있다.

                  // Exam0340.this.iValue = 100; // 이렇게 Exam0340에서 넘겨준 주소를 this.에 저장할 수 있다.

Exam0350 -> 로컬 클래스와 로컬 변수 // 로컬 클래스는 로컬 변수를 사용할 수 있다.

Exam0351 -> 로컬 변수의 final 상수 변수화 // final로 할당하지 않아도 한번만 할당됐으면 final로 간주.

Exam0352 -> 로컬 클래스가 로컬 변수를 사용할 수 없을 때 // 로컬 변수의 값이 final이 아닐때 사용 불가능.

Exam0353 -> 로컬 클래스가 로컬 변수의 값을 바꿀 수 없다 // 단지 로컬 변수의 값을 조회만 가능하다.

Exam0360 -> 로컬 클래스가 로컬 변수를 사용하는 법 // 로컬 클래스는 로컬 변수를 직접 사용하지 않는다.

                  // 생성자를 통해 전달받은 로컬 변수를 복사한 값을 사용한다. // 따라서 값을 변경하거나 할 수 없다.

                  // return new A(); => 실제 처리하는 되는 과정은 new A(this, name(로컬변수));와 같이

                  // 바깥 클레스의 this 주소값과 로컬 변수의 값을 받아 로컬 변수의 값을 복사하여 사용한다.

                  // 로컬 변수가 여러개라면, 여러개를 다 전달받고 복사하여 사용한다.

Exam0410 -> 로컬클래스로 인터페이스 구현

Exam0420 -> 익명클래스로 인터페이스 구현

Exam0421 -> 람다 (lambda) 표기법

Exam0430 -> 익명클래스로 추상클래스 구현

Exam0431 -> lambda 문법 사용 불가 // class에 대해서는 람다 문법 사용이 불가하다.

Exam0440 -> 생성자에 따른 익명클래스 구현

Exam0450 -> 익명클래스의 오버라이딩

Exam0510 -> 익명클래스가 놓이는 장소 1 : 스태틱 필드

                  // 스태틱 필드에 익명클래스를 사용할 수 있다.

Exam0520 -> 익명클래스가 놓이는 장소 2 : 인스턴스 필드

Exam0530 -> 익명클래스가 놓이는 장소 3 : 로컬 변수

Exam0540 -> 익명클래스가 놓이는 장소 4 : 파라미터

Exam0541 -> 익명클래스가 놓이는 장소 4 : 파라미터 + 람다 문법

 

#ex11 b

Exam0110 -> package 멤버 클래스 사용 // java.io.File 클래스 사용

Exam0111 -> java 파일만 걸러내는 JavaFilter 클래스를 별도로 생성함.

Exam0120 -> static nested class (스태틱 클래스) 

                  // 바깥 클레스의 인스턴스를 사용하지 않는다면 static nested class로 선언하자.

Exam0130 -> non-static nested class(inner class = 인스턴스 클래스)

                  // 바깥 클레스의 인스턴스를 사용한다면 no-static nested class로 선언하자.

Exam0131 -> static 메소드에서 인스턴스 클래스를 사용하는 방법. // 상위 클래스를 호출 후, 인스턴스 클래스 호출

Exam0140 -> local class (로컬 클래스)

Exam0150 -> anonymous class(익명 클래스) 

Exam0160 -> 파라미터에 anonymous class 적용

Exam0161 -> anonymous class를 lambda 문법 적용하기

Exam0170 -> 클래스(class)의 종류와 특성 

 

#ex11 c

Step1 -> 원래 예전에는 주석으로 카테고리등을 분류하였다. // 표기 불편

Step2 -> 주석을 달지 않고, 문자열로 입력 받았다 // 오타 발생

Step3 -> 문자열을 final 값으로 정해두고 클래스로 관리했다 // String이라 메모리 낭비

Step4 -> 문자열을 변수로 저장하여 int로 관리 // 변수명이 너무 길어 직관적이지 않다.

Step5 -> static 멤버를 import하여 사용 // 한 class에 카테고리 변수명과, 카테고리 상수가 같이 있어 직관적이지 않다.

Step6 -> class를 카테고리에 맞게 분류 // 너무 자잘하게 분리하여 관리할 class파일이 많아서 관리하기 불편하다.

Step7 -> static nested class 사용 // static 중첩 클래스를 사용하여, 한 파일에 관리를 한다.

            // OGNL(Object Graph Navigation Language)를 이용하여 카테고리 위치를 가리킨다.

            // 객체.필드.필드.필드 // p.category = Category.appliance.TV;

 

#ex12

Exam0110 -> 추상메서드가 한개인 인터페이스 // functional interface

Exam0111 -> 익명클래스로 인터페이스 구현

Exam0112 -> 람다(lambda) 문법으로 인터페이스 구현 // 람다는 메소드 한개만 가능하다.(functional interface)

                  // 메소드가 여러개이면 파라미터로 넘긴 값을 어떤 메소드가 사용해야될 지 모르기 때문.

                  // 인터페이스명 레퍼런스 = (파라미터) -> 구현문장 // Player p1 = () -> Sysout("실행")

Exam0113 -> {}는 문장이 하나라면 람다 문법 적용시 생략이 가능하다.

Exam0114 -> 파라미터가 없어도 ()를 생략할 수는 없다. // Player p1 =  -> Sysout("실행") // 불가능.

Exam0120 -> 람다 문법 몸통 구현 // 문장(추상 메서드)이 하나일 경우 {} 생략 가능

Exam0130 -> 람다 문법 파라미터 // 파라미터에 값을 넘겨주면 된다. // 인터페이스에 받을 파라미터도 존재해야함.

                  // 파라미터의 타입도 생략할 수 있다 ex) String int 등등. 단 넘겨줄 때에(인터페이스 선언에는 있어야함.)

                  // 파라미터를 한개만 받는다면 람다 문법에서 ()생략 할 수 있다. // Player p1 = name -> Sysout("실행")

                  // 그렇다고 파라미터가 없다고 ()를 생략할 수는 없다. -> #ex12 Exam0113

Exam0140 -> 람다 문법 파라미터 // 파라미터가 2개 이상인 경우에는 ()를 생략할 수 없다.

Exam0150 -> 람다 문법 리턴값 // 리턴 값이 있는 경우 표현식(expression)이 와야한다.

                   // 표현식? // 실행한 후 결과과 리턴되는 명령

                   // 리턴 값이 있는 경우에는 {}를 생략하려고 할때에는 return도 같이 생략해야한다.

                   // c1 = (a, b) -> a + b; // c1 = (a, b) -> {return a + b}; // 리턴이 있을거면 {}도 붙여야함.

Exam0210 -> 메서드가 하나 있는 람다

Exam0220 -> 추상 메서드가 한개인 경우에 람다 적용 가능. // stop()은 default로 구현, info()는 구현되어 있음.

Exam0230 -> 추상 메서드가 두개인 경우에는 람다 적용 불가능

Exam0240 -> 추상클래스인 경우에 람다 문법은 사용 불가.

 

Exam0310 -> 익명클래스가 나온 이유

                  // 객체를 하나밖에 안만드는데 클래스까지 만들어, 객체를 넘기는게 비효율 적이다 판단

Exam0311 -> 익명클래스 적용 1단계 // 클래스를 따로 만들지 않고 레퍼런스로 바로 넣음.

Exam0312 -> 익명클래스 적용 2단계 // 레퍼런스를 따로 만들지 않고 파라미터에 바로 넣음.

                  // 객체를 쓰는 데가 한 곳이라면, 굳이 레퍼런스를 만들지 않는다.

Exam0313 -> 익명클래스 람다 적용 // 문장이 하나라면, lambda를 적용한다.

Exam0320 -> 람다 문법 파라미터 // 파라미터가 두개인 경우

Exam0321 -> 람다 문법이 없었을 경우 // Exam0320 익명클래스로 정의함.

Exam0330 -> 문장이 여러개인 경우 람다 문법 적용

Exam0331 -> 람다 문법이 없었을 경우 // Exam0330 익명클래스로 정의함.

Exam0410 -> 로컬 클래스에서 바깥 변수 사용

Exam0411 -> 바깥 변수를 저장할 변수와 값을 전달할 생성자 선언 필요 없음.

                  // 컴파일러가 자동으로 Exam0410처럼 내부적으로 알아서 만들어줌.

Exam0412 -> Exam0411을 익명클래스 적용 1단계로 변경 // Interest를 받을 래퍼런스 생성 및 메서드를 넘기고 리턴.

Exam0413 -> Exam0412를 익명클래스 적용 2단계로 변경 // 래퍼런스 생성을 하지말고 리턴에 메서드를 넣는다.

Exam0414 -> Exam0413을 람다 문법 적용으로 변경 // 굳이 메서드를 다 적지 말고 파라미터와 리턴값만 가져온다.

Exam0510 -> 스태틱 메서드 레퍼런스 // 인터페이스에 선언된 메서드 규격이 같다면 람다 문법으로 선언 가능하다.

                  // 클래스명::메서드명; // Calculator1 c1 = MyCalculator::plus;

                  // 인터페이스를 단순한 기능만 담당하게 한다. ex)계산해라. // 단, 인터페이스 메서드가 하나여야 함.

                  // 인터페이스 레퍼런스를 생성한 후, 메서드 레퍼런스에서 어떠한 메서드를 골라 상황에 맞게 넣는다.

                  // Calculator1 c1 = MyCalculator::plus; // 계산하라는 인터페이스의 레퍼런스(c1)를 생성

                  // 상세 기능을 골라 담당할(+ - * / 년이자 월이자 일이자) 메서드(MyCalculator::plus)를 넣어준다.

                  // c1.compute(100,200) // c1에 넣은 plus 메서드에 100, 200을 전달하고 값을 리턴받는다.

Exam0520 -> 스태틱 메서드 레퍼런스로 인터페이스 구현체 만들기 // 인터페이스 주소에 규격 통과 메서드를 넣는다.

                  // 인터페이스에 메서드 레퍼런스를 넣기 위해서는, 둘의 파라미터와 리턴타입의 규격이 같아야 한다.

                  // 호출 될 시, 인스턴스의 메서드 파라미터로 넘어온 값을 스태틱 메서드 레퍼런스에게 전달한다.

                  // 스태틱 메서드 레퍼런스가 파라미터로 받은 값을 실행 후, 리턴 한다. // 따라서 둘의 규격이 같아야 함.

Exam0530 -> 리턴타입의 규칙 // 리턴타입이 같거나, 암시적 형변환이 가능하거나, 오토박싱이 가능하거나, void만 가능

Exam0540 -> 파라미터의 규칙 // 리턴타입의 규칙과 같다. 작은데(ex byte, short)에서 큰걸(ex int)로는 가능함.

Exam0610 -> 인스턴스 메서드 레퍼런스 // 레퍼런스를 미리 만들고, 안의 메서드를 사용해야 한다.

                   // 인스턴스::메서드명 // Interest i1 = 보통예금::year;

                   // 미리 생성자를 통해 인스턴스 메서드 레퍼런스(보통예금)를 생성한다.

                   // 인터페이스의 레퍼런스(i1)에 인스턴스 메서드(보통예금::year)를 씌운다.

                   // i1.compute(10_0000_0000) // i1에 넣은 year메서드에 10_0000_0000을 전달하고 값을 리턴받는다.

Exam0620 -> 인스턴스 메서드 레퍼런스로 인터페이스 구현체 만들기 // 파라미터와 리턴타입의 규칙이 같아야한다.

Exam0710 -> 메서드 레퍼런스를 인터페이스 생성자로 만들기 //

                  // 메서드 레퍼런스에 정의된 메서드가 인터페이스의 생성자 형식과 일치하다면

                  // 형식이 같은 일반 메서드 레퍼런스를 생성자처럼 사용할 수 있다.

                  // ListFactory f1 = ArrayList::new; // 인터페이스 ListFactory의 레퍼런스 f1에 

                  // ArrayList의 new 메서드를 씌우고, ListFactory의 메서드 create()를 실행하면

                  // ArrayList의 new 명령인 // new ArrayList()가 실행된다. // 생성자로써 활용 가능하다.

Exam0720 -> ListFactory f1 = ArrayList::new; // 익명 클래스로 new ArrayList하는 것과 같다.

Exam0730 -> 메서드 레퍼런스를 인터페이스 생성자로 만들기 // 다양한 파라미터

                  // 오버로딩이 된 메서드가 연결된 인터페이스의 규칙에 맞춰 생성자 역할을 한다.

Exam0740 -> 메서드 레퍼런스를 인터페이스 생성자로 만들기 // 다양한 파라미터

                  // 오버로딩이 된 메서드가 연결된 인터페이스의 규칙에 맞는 파라미터를 가지고 있지 않다면.

                  // 생성자 역할을 할 수 없으며 당연히, 인터페이스 구현체가 될 수 없다 // 컴파일 오류.

Exam0750 -> 생성자 레퍼런스의 활용 // Supplier 클래스의 생성자 호출을 ArrayList::new로 대신함.

반응형

+ Recent posts