대학레포트

고객센터 안내 (02)539-9392 평일 : 오전 09:00 ~ 오후 18:00 점심시간 : 12:00 ~ 13:00 토, 일, 법정공휴일 휴무

  • img
  • 5 패키지
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편5. 패키지#1.인강/0.자바/2.자바-기본/패키지 - 시작/패키지 - import /패키지 규칙/패키지 활용/정리패키지 - 시작여러분이 쇼핑몰 시스템을 개발한다고 가정해보자. 다음과 같이 프로그램이 매우 작고 단순해서 클래스가 몇게 없다면크게 고민할 거리가 없겠지만, 기능이 점점 추가되어서 프로그램이 아주 커지게 된다면 어떻게 될까?**아주 작은 프로그램**```OrderUserProduct```**큰 프로그램**```UserUserManagerUserHistoryProductProductCatalogProductImageOrderOrderServiceOrderHistoryShoppingCartCartItemPaymentPaymentHistoryShipmentShipmentTracker```매우 많은 클래스가 등장하면서 관련 있는 기능들을 분류해서 관리하고 싶을 것이다.컴퓨터는 보통 파일을 분류하기 위해 폴더, 디렉토리라는 개념을 제공한다. 자바도 이런 개념을 제공하는데, 이것이 바로 패키지이다.다음과 같이 카테고리를 만들고 분류해보자.```* user* User* UserManager* UserHistory* product* Product* ProductCatalog* ProductImage* order* Order* OrderService* OrderHistory* cart* ShoppingCart* CartItem* payment* Payment* PaymentHistory* shipping* Shipment* ShipmentTracker```여기서 `user `, `product `등이 바로 패키지이다. 그리고 해당 패키지 안에 관련된 자바 클래스들을 넣으면 된다.패키지(package)는 이름 그대로 물건을 운송하기 위한 포장 용기나 그 포장 묶음을 뜻한다.패키지 사용패키지 사용법을 코드로 확인해보자.패키지를 먼저 만들고 그 다음에 클래스를 만들어야 한다.**패키지 위치에 주의하자.****pack.Data **```javapackage pack;public class Data public Data() System.out.println(패키지 pack Data 생성);```**패키지를 사용하는 경우 항상 코드 첫줄에 `package pack `과 같이 패키지 이름을 적어주어야 한다.**여기서는 `pack ` 패키지에 `Data ` 클래스를 만들었다.이후에 `Data ` 인스턴스가 생성되면 생성자를 통해 정보를 출력한다.**pack.a.User **```javapackage pack.a;public class User public User() System.out.println(패키지 pack.a 회원 생성);````pack ` 하위에 `a`라는 패키지를 먼저 만들자.`pack.a ` 패키지에 `User ` 클래스를 만들었다.이후에 `User ` 인스턴스가 생성되면 생성자를 통해 정보를 출력한다.**참고**: 생성자에 `public `을 사용했다. 다른 패키지에서 이 클래스의 생성자를 호출하려면 `public `을 사용해야 한다.자세한 내용은 접근 제어자에서 설명한다. 지금은 코드와 같이 생성자에 `public ` 키워드를 넣어두자.**pack.PackageMain1**```javapackage pack;public class PackageMain1 public static void main(String args) Data data = new Data();pack.a.User user = new pack.a.User();````pack ` 패키지 위치에 `PackageMain1 ` 클래스를 만들었다.**실행 결과**```패키지 pack Data 생성패키지 pack.a 회원 생성```**사용자와 같은 위치:** `PackageMain1 `과 `Data `는 같은 `pack `이라는 패키지에 소속되어 있다. 이렇게 같은 패키지에 있는 경우에는 패키지 경로를 생략해도 된다.**사용자와 다른 위치:** `PackageMain1 `과 `User `는 서로 다른 패키지다. 이렇게 패키지가 다르면`pack.a.User `와 같이 패키지 전체 경로를 포함해서 클래스를 적어주어야 한다.패키지 - importimport이전에 본 코드와 같이 패키지가 다르다고 `pack.a.User `와 같이 항상 전체 경로를 적어주는 것은 불편하다. 이때는`import `를 사용하면 된다.```javapackage pack;import pack.a.User;public class PackageMain2 public static void main(String args) Data data = new Data();User user = new User(); //import 사용으로 패키지 명 생략 가능```**실행 결과**```패키지 pack Data 생성패키지 pack.a 회원 생성```코드에서 첫줄에는 `package `를 사용하고, 다음 줄에는 `import `를 사용할 수 있다.`import `를 사용하면 다른 패키지에 있는 클래스를 가져와서 사용할 수 있다.`import `를 사용한 덕분에 코드에서는 패키지 명을 생략하고 클래스 이름만 적을 수 있다.참고로 특정 패키지에 포함된 모든 클래스를 포함해서 사용하고 싶으면 `import ` 시점에 `*(별)`을 사용하면 된다.**패키지 별(*) 사용**```javapackage pack;

    2024.05.11 / 9pages ( 대학레포트 > 시험/강의/학업)

    태그 사용 패키지 , 생성자 클래스 , 5 패키지
  • img
  • 6 접근 제어자
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편6. 접근 제어자#1.인강/0.자바/2.자바-기본/접근 제어자 이해1/접근 제어자 이해2/접근 제어자 종류/접근 제어자 사용 - 필드, 메서드/접근 제어자 사용 - 클래스 레벨/캡슐화/문제와 풀이/정리접근 제어자 이해1자바는 `public `, `private ` 같은 접근 제어자(access modifier)를 제공한다. 접근 제어자를 사용하면 해당 클래스외부에서 특정 필드나 메서드에 접근하는 것을 허용하거나 제한할 수 있다.이런 접근 제어자가 왜 필요할까? 예제를 통해 접근 제어자가 필요한 이유를 알아보자.여러분은 스피커에 들어가는 소프트웨어를 개발하는 개발자다.스피커의 음량은 절대로 100을 넘으면 안된다는 요구사항이 있다. (**100을 넘어가면 스피커의 부품들이 고장난다.**)스피커 객체를 만들어보자.스피커는 음량을 높이고, 내리고, 현재 음량을 확인할 수 있는 단순한 기능을 제공한다.요구사항 대로 스피커의 음량은 100까지만 증가할 수 있다. 절대 100을 넘어가면 안된다.**Speaker**```javapackage access;public class Speaker int volume;Speaker(int volume) this.volume = volume;void volumeUp() if (volume >= 100) System.out.println(음량을 증가할 수 없습니다. 최대 음량입니다.); else volume += 10;System.out.println(음량을 10 증가합니다.);void volumeDown() volume -= 10;System.out.println(volumeDown 호출);void showVolume() System.out.println(현재 음량: + volume);```생성자를 통해 초기 음량 값을 지정할 수 있다.`volumeUp() ` 메서드를 보자. 음량을 한번에 10씩 증가한다. 단 음량이 100을 넘게되면 더는 음량을 증가하지 않는다.**SpeakerMain**```javapackage access;public class SpeakerMain public static void main(String args) Speaker speaker = new Speaker(90);speaker.showVolume();speaker.volumeUp();speaker.showVolume();speaker.volumeUp();speaker.showVolume();```**실행 결과**```현재 음량: 90음량을 10 증가합니다.현재 음량: 100음량을 증가할 수 없습니다. 최대 음량입니다.현재 음량: 100```초기 음량 값을 90으로 지정했다. 그리고 음량을 높이는 메서드를 여러번 호출했다.기대한 대로 음량은 100을 넘지 않았다. 프로젝트는 성공적으로 끝났다.오랜 시간이 흘러서 업그레이드 된 다음 버전의 스피커를 출시하게 되었다. 이때는 새로운 개발자가 급하게 기존 코드를이어받아서 개발을 하게 되었다. 참고로 새로운 개발자는 기존 요구사항을 잘 몰랐다. 코드를 실행해보니 이상하게 음량이 100이상 올라가지 않았다. 소리를 더 올리면 좋겠다고 생각한 개발자는 다양한 방면으로 고민했다.`Speaker ` 클래스를 보니 `volume ` 필드를 직접 사용할 수 있었다. `volume ` 필드의 값을 200으로 설정하고 이 코드를 실행한 순간 스피커의 부품들에 과부하가 걸리면서 폭발했다.**SpeakerMain - 필드 직접 접근 코드 추가**```javapackage access;public class SpeakerMain public static void main(String args) Speaker speaker = new Speaker(90);speaker.showVolume();speaker.volumeUp();speaker.showVolume();speaker.volumeUp();speaker.showVolume();//필드에 직접 접근System.out.println(volume 필드 직접 접근 수정);speaker.volume = 200;speaker.showVolume();```**실행 결과**```현재 음량: 90음량을 10 증가합니다.현재 음량: 100음량을 증가할 수 없습니다. 최대 음량입니다.현재 음량: 100volume 필드 직접 접근 수정현재 음량: 200```**volume 필드**`Speaker ` 객체를 사용하는 사용자는 `Speaker `의 `volume ` 필드와 메서드에 모두 접근할 수 있다.앞서 `volumeUp() `과 같은 메서드를 만들어서 음량이 100을 넘지 못하도록 기능을 개발했지만 소용이 없다. 왜냐하면 `Speaker `를 사용하는 입장에서는 `volume ` 필드에 직접 접근해서 원하는 값을 설정할 수 있기 때문이다.이런 문제를 근본적으로 해결하기 위해서는 `volume ` 필드의 외부 접근을 막을 수 있는 방법이 필요하다.접근 제어자 이해2이 문제를 근본적으로 해결하는 방법은 `volume ` 필드를 `Speaker ` 클래스 외부에서는 접근하지 못하게 막는 것이다.**Speaker - volume 접근 제어자를 private으로 수정**```javapackage access;public class Speaker private int volume; //private 사용.````private ` 접근 제어자는 모든 외부 호출을 막는다. 따라서 `private `이 붙은 경우 해당 클래스 내부에서만 호출할 수 있다.**volume 필드 - private 변경 후**그림을 보면 `volume ` 필드를 `private `을 사용해서 `Speaker ` 내부에 숨겼다.외부에서 `volume ` 필드에 직접 접근할 수 없게 막은 것이다. `volume ` 필드는 이제 `Speaker ` 내부에서만 접근할 수있다.이제 `SpeakerMain ` 코드를 다시 실행해보자.```java//필드에 직접 접근System.out.println(volume 필드 직접 접근 수정);speaker.volume = 200; //private 접근 오류```IDE에서 `speaker.volume = 200 ` 부분에 오류가 발생하는 것을 확인할 수 있다. 실행해보면 다음과 같은 컴파일오류가 발생한다.컴파일 오류 메시지```volume has private access in access.Speaker````volume ` 필드는 `private `으로 설정되어 있기 때문에 외부에서 접근할 수 없다는 오류이다.**volume 필드 직접 접근 - 주석 처리**```java//필드에 직접 접근System.out.println(volume 필드 직접 접근 수정);//speaker.volume = 200; //private 접근 오류speaker.showVolume();```이제 `Speaker ` 외부에서 `volume ` 필드에 직접 접근하는 것은 불가능하다. 이 경우 자바 컴파일러가 컴파일 오류를발생시킨다.프로그램을 실행하기 위해서 `volume ` 필드에 직접 접근하는 코드를 주석 처리하자.

    2024.05.11 / 20pages ( 대학레포트 > 시험/강의/학업)

    태그 메서드 접근 , 직접 제어자 , 6 접근 제어자
  • img
  • 7 자바 메모리 구조와 static
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편7. 자바 메모리 구조와 static#1.인강/0.자바/2.자바-기본/자바 메모리 구조/스택과 큐 자료 구조/스택 영역/스택 영역과 힙 영역/static 변수1/static 변수2/static 변수3/static 메서드1/static 메서드2/static 메서드3/문제와 풀이/정리자바 메모리 구조**자바 메모리 구조 - 비유**자바의 메모리 구조는 크게 메서드 영역, 스택 영역, 힙 영역 3개로 나눌 수 있다.**메서드 영역**: 클래스 정보를 보관한다. 이 클래스 정보가 붕어빵 틀이다.**스택 영역**: 실제 프로그램이 실행되는 영역이다. 메서드를 실행할 때 마다 하나씩 쌓인다.**힙 영역**: 객체(인스턴스)가 생성되는 영역이다. `new` 명령어를 사용하면 이 영역을 사용한다. 쉽게 이야기해서 붕어빵 틀로부터 생성된 붕어빵이 존재하는 공간이다. 참고로 배열도 이 영역에 생성된다.방금 설명한 내용은 쉽게 비유로 한 것이고 실제는 다음과 같다.**자바 메모리 구조 - 실제****메서드 영역(Method Area) **: 메서드 영역은 프로그램을 실행하는데 필요한 공통 데이터를 관리한다. 이 영역은프로그램의 모든 영역에서 공유한다.클래스 정보: 클래스의 실행 코드(바이트 코드), 필드, 메서드와 생성자 코드등 모든 실행 코드가 존재한다.static 영역: `static ` 변수들을 보관한다. 뒤에서 자세히 설명한다.런타임 상수 풀: 프로그램을 실행하는데 필요한 공통 리터럴 상수를 보관한다. 예를 들어서 프로그램에`hello `라는 리터럴 문자가 있으면 이런 문자를 공통으로 묶어서 관리한다. 이 외에도 프로그램을 효율적으로 관리하기 위한 상수들을 관리한다. (참고로 문자열을 다루는 문자열 풀은 자바 7부터 힙 영역으로 이동했다.)**스택 영역(Stack Area) **: 자바 실행 시, 하나의 실행 스택이 생성된다. 각 스택 프레임은 지역 변수, 중간 연산 결과, 메서드 호출 정보 등을 포함한다.스택 프레임: 스택 영역에 쌓이는 네모 박스가 하나의 스택 프레임이다. 메서드를 호출할 때 마다 하나의 스택 프레임이 쌓이고, 메서드가 종료되면 해당 스택 프레임이 제거된다.**힙 영역(Heap Area) **: 객체(인스턴스)와 배열이 생성되는 영역이다. 가비지 컬렉션(GC)이 이루어지는 주요 영역이며, 더 이상 참조되지 않는 객체는 GC에 의해 제거된다.**참고**: 스택 영역은 더 정확히는 각 쓰레드별로 하나의 실행 스택이 생성된다. 따라서 쓰레드 수 만큼 스택 영역이생성된다. 지금은 쓰레드를 1개만 사용하므로 스택 영역도 하나이다. 쓰레드에 대한 부분은 멀티 쓰레드를 학습해야 이해할 수 있다.**메서드 코드는 메서드 영역에**자바에서 특정 클래스로 100개의 인스턴스를 생성하면, 힙 메모리에 100개의 인스턴스가 생긴다. 각각의 인스턴스는내부에 변수와 메서드를 가진다. 같은 클래스로 부터 생성된 객체라도, 인스턴스 내부의 변수 값은 서로 다를 수 있지만,메서드는 공통된 코드를 공유한다. 따라서 객체가 생성될 때, 인스턴스 변수에는 메모리가 할당되지만, 메서드에 대한새로운 메모리 할당은 없다. 메서드는 메서드 영역에서 공통으로 관리되고 실행된다.정리하면 인스턴스의 메서드를 호출하면 실제로는 메서드 영역에 있는 코드를 불러서 수행한다.스택과 큐 자료 구조자바 메모리 구조 중 스택 영역에 대해 알아보기 전에 먼저 스택(Stack)이라는 자료 구조에 대해서 알아보자.스택 구조다음과 같은 1, 2, 3 이름표가 붙은 블럭이 있다고 가정하자.이 블럭을 다음과 같이 생긴 통에 넣는다고 생각해보자. 위쪽만 열려있기 때문에 위쪽으로 블럭을 넣고, 위쪽으로 블럭을 빼야 한다. 쉽게 이야기해서 넣는 곳과 빼는 곳이 같다.블럭은 1 2 3 순서대로 넣을 수 있다.이번에는 넣은 블럭을 빼자.블럭을 빼려면 위에서 부터 순서대로 빼야한다.블럭은 3 2 1 순서로 뺄 수 있다.정리하면 다음과 같다.1(넣기) 2(넣기) 3(넣기) 3(빼기) 2(빼기) 1(빼기)**후입 선출(LIFO, Last In First Out)**여기서 가장 마지막에 넣은 3번이 가장 먼저 나온다. 이렇게 나중에 넣은 것이 가장 먼저 나오는 것을 후입 선출이라 하고, 이런 자료 구조를 스택이라 한다.**선입 선출(FIFO, First In First Out)**후입 선출과 반대로 가장 먼저 넣은 것이 가장 먼저 나오는 것을 선입 선출이라 한다. 이런 자료 구조를 큐(Queue)라 한다.**큐(Queue) 자료 구조**정리하면 다음과 같다.1(넣기) 2(넣기) 3(넣기) 1(빼기) 2(빼기) 3(빼기)이런 자료 구조는 각자 필요한 영역이 있다. 예를 들어서 선착순 이벤트를 하는데 고객이 대기해야 한다면 큐 자료 구조를 사용해야 한다.이번시간에 중요한 것은 스택이다. 프로그램 실행과 메서드 호출에는 스택 구조가 적합하다. 스택 구조를 학습했으니,자바에서 스택 영역이 어떤 방식으로 작동하는지 알아보자.스택 영역다음 코드를 실행하면 스택 영역에서 어떤 변화가 있는지 확인해보자.**JavaMemoryMain1**```javapackage memory;public class JavaMemoryMain1 public static void main(String args) System.out.println(main start);method1(10);System.out.println(main end);static void method1(int m1) System.out.println(method1 start);int cal = m1 * 2;method2(cal);System.out.println(method1 end);static void method2(int m2) System.out.println(method2 start);System.out.println(method2 end);```**실행 결과**```main startmethod1 startmethod2 startmethod2 endmethod1 endmain end```**호출 그림** 처음 자바 프로그램을 실행하면 `main() `을 실행한다. 이때 `main() `을 위한 스택 프레임이 하나 생성된다.`main() ` 스택 프레임은 내부에 `args `라는 매개변수를 가진다. `args `는 뒤에서 다룬다.`main() `은 `method1() `을 호출한다. `method1() ` 스택 프레임이 생성된다.`method1() `는 `m1`, `cal` 지역 변수(매개변수 포함)를 가지므로 해당 지역 변수들이 스택 프레임에 포함된다.`method1() `은 `method2() `를 호출한다. `method2() ` 스택 프레임이 생성된다. `method2() `는 `m2` 지역 변수(매개변수 포함)를 가지므로 해당 지역 변수가 스택 프레임에 포함된다.**종료 그림**`method2() `가 종료된다. 이때 `method2() ` 스택 프레임이 제거되고, 매개변수 `m2`도 제거된다. `method2() `스택 프레임이 제거 되었으므로 프로그램은 `method1() `로 돌아간다. 물론 `method1() `을 처음부터 시작하는것이 아니라 `method1() `에서 `method2() `를 호출한 지점으로 돌아간다.`method1() `이 종료된다. 이때 `method1() ` 스택 프레임이 제거되고, 지역 변수(매개변수 포함) `m1`, `cal`도제거된다. 프로그램은 `main() `으로 돌아간다.`main() `이 종료된다. 더 이상 호출할 메서드가 없고, 스택 프레임도 완전히 비워졌다. 자바는 프로그램을 정리하고 종료한다.**정리**자바는 스택 영역을 사용해서 메서드 호출과 지역 변수(매개변수 포함)를 관리한다.메서드를 계속 호출하면 스택 프레임이 계속 쌓인다.지역 변수(매개변수 포함)는 스택 영역에서 관리한다.스택 프레임이 종료되면 지역 변수도 함께 제거된다.스택 프레임이 모두 제거되면 프로그램도 종료된다.

    2024.05.11 / 35pages ( 대학레포트 > 시험/강의/학업)

    태그 자바 스택 , 구조 메서드 , 7 자바 메모리 구
  • img
  • 8 final
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편8. final#1.인강/0.자바/2.자바-기본/final 변수와 상수1/final 변수와 상수2/final 변수와 참조/정리final 변수와 상수1`final ` 키워드는 이름 그대로 끝! 이라는 뜻이다.변수에 `final ` 키워드가 붙으면 더는 값을 변경할 수 없다.참고로 `final `은 `class `, `method `를 포함한 여러 곳에 붙을 수 있다. 지금은 변수에 붙는 `final ` 키워드를 알아보자. 나머지는 `final `의 사용법은 상속을 설명한 이후에 설명한다.final - 지역 변수```javapackage final1;public class FinalLocalMain public static void main(String args) //final 지역 변수1final int data1;data1 = 10; //최초 한번만 할당 가능//data1 = 20; //컴파일 오류//final 지역 변수2final int data2 = 10;//data2 = 20; //컴파일 오류method(10);//final 매개변수static void method(final int parameter) //parameter = 20; 컴파일 오류````final `을 지역 변수에 설정할 경우 최초 한번만 할당할 수 있다. 이후에 변수의 값을 변경하려면 컴파일 오류가발생한다.`final `을 지역 변수 선언시 바로 초기화 한 경우 이미 값이 할당되었기 때문에 값을 할당할 수 없다.매개변수에 `final `이 붙으면 메서드 내부에서 매개변수의 값을 변경할 수 없다. 따라서 메서드 호출 시점에 사용된 값이 끝까지 사용된다.final - 필드(멤버 변수)```javapackage final1;//final 필드 - 생성자 초기화public class ConstructInit final int value;public ConstructInit(int value) this.value = value;````final `을 필드에 사용할 경우 해당 필드는 생성자를 통해서 한번만 초기화 될 수 있다.```javapackage final1;//final 필드 - 필드 초기화public class FieldInit static final int CONSTVALUE = 10;final int value = 10;````final ` 필드를 필드에서 초기화하면 이미 값이 설정되었기 때문에 생성자를 통해서도 초기화 할 수 없다.`value ` 필드를 참고하자.코드에서 보는 것 처럼 `static ` 변수에도 `final `을 선언할 수 있다.`CONSTVALUE `로 변수 작명 방법이 대문자를 사용했는데, 이 부분은 바로 뒤에 상수에서 설명한다.```javapackage final1;public class FinalFieldMain public static void main(String args) //final 필드 - 생성자 초기화System.out.println(생성자 초기화);ConstructInit constructInit1 = new ConstructInit(10);ConstructInit constructInit2 = new ConstructInit(20);System.out.println(constructInit1.value);System.out.println(constructInit2.value);//final 필드 - 필드 초기화System.out.println(필드 초기화);FieldInit fieldInit1 = new FieldInit();FieldInit fieldInit2 = new FieldInit();FieldInit fieldInit3 = new FieldInit();System.out.println(fieldInit1.value);System.out.println(fieldInit2.value);System.out.println(fieldInit3.value);//상수System.out.println(상수);System.out.println(FieldInit.CONSTVALUE);```**실행 결과**```생성자 초기화1020필드 초기화10상수10````ConstructInit `과 같이 생성자를 사용해서 `final ` 필드를 초기화 하는 경우, 각 인스턴스마다 `final ` 필드에 다른 값을 할당할 수 있다. 물론 `final `을 사용했기 때문에 생성 이후에 이 값을 변경하는 것은 불가능하다.

    2024.05.11 / 10pages ( 대학레포트 > 시험/강의/학업)

    태그 지역 변수 , 생성자 초기화 , 8 final
  • img
  • 9 상속
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편9. 상속#1.인강/0.자바/2.자바-기본/상속 - 시작/상속 관계/상속과 메모리 구조/상속과 기능 추가/상속과 메서드 오버라이딩/상속과 접근 제어/super - 부모 참조/super - 생성자/문제와 풀이/정리상속 - 시작상속 관계가 왜 필요한지 이해하기 위해 다음 예제 코드를 만들어서 실행해보자.예제 코드**패키지 위치에 주의하자**```javapackage extends1.ex1;public class ElectricCar public void move() System.out.println(차를 이동합니다.);public void charge() System.out.println(충전합니다.);```javapackage extends1.ex1;public class GasCar public void move() System.out.println(차를 이동합니다.);public void fillUp() System.out.println(기름을 주유합니다.);```javapackage extends1.ex1;public class CarMain public static void main(String args) ElectricCar electricCar = new ElectricCar();electricCar.move();electricCar.charge();GasCar gasCar = new GasCar();gasCar.move();gasCar.fillUp();```**실행 결과**```차를 이동합니다.충전합니다.차를 이동합니다.기름을 주유합니다.``` 전기차( `ElectricCar `)와 가솔린차( `GasCar `)를 만들었다. 전기차는 이동( `move() `), 충전( `charge() `) 기능이 있고, 가솔린차는 이동( `move() `), 주유( `fillUp() `) 기능이 있다.전기차와 가솔린차는 자동차( `Car`)의 좀 더 구체적인 개념이다. 반대로 자동차( `Car`)는 전기차와 가솔린차를 포함하는추상적인 개념이다. 그래서인지 잘 보면 둘의 공통 기능이 보인다. 바로 이동( `move() `)이다.전기차든 가솔린차든 주유하는 방식이 다른 것이지 이동하는 것은 똑같다. 이런 경우 상속 관계를 사용하는 것이 효과적이다.상속 관계상속은 객체 지향 프로그래밍의 핵심 요소 중 하나로, 기존 클래스의 필드와 메서드를 새로운 클래스에서 재사용하게 해준다. 이름 그대로 기존 클래스의 속성과 기능을 그대로 물려받는 것이다. 상속을 사용하려면 `extends ` 키워드를 사용하면 된다. 그리고 `extends ` **대상은 하나만 선택**할 수 있다.**용어 정리****부모 클래스 (슈퍼 클래스)**: 상속을 통해 자신의 필드와 메서드를 다른 클래스에 제공하는 클래스**자식 클래스 (서브 클래스)**: 부모 클래스로부터 필드와 메서드를 상속받는 클래스**주의!****지금부터 코드를 작성할 때 기존 코드를 유지하기 위해, 새로운 패키지에 기존 코드를 옮겨가면서 코드를 작성할 것이다.클래스의 이름이 같기 때문에 패키지 명과 import 사용에 주의해야 한다.**상속 관계를 사용하도록 코드를 작성해보자.**기존 코드를 유지하기 위해 ex2 패키지를 새로 만들자**```javapackage extends1.ex2;public class Car public void move() System.out.println(차를 이동합니다.);````Car`는 부모 클래스가 된다. 여기에는 자동차의 공통 기능인 `move() `가 포함되어 있다.```javapackage extends1.ex2;public class ElectricCar extends Car public void charge() System.out.println(충전합니다.);```전기차는 `extends Car `를 사용해서 부모 클래스인 `Car`를 상속 받는다. 상속 덕분에 `ElectricCar `에서도`move() `를 사용할 수 있다.```javapackage extends1.ex2;public class GasCar extends Car public void fillUp() System.out.println(기름을 주유합니다.);```가솔린차도 전기차와 마찬가지로 `extends Car `를 사용해서 부모 클래스인 `Car`를 상속 받는다. 상속 덕분에 여기서도 `move() `를 사용할 수 있다.```javapackage extends1.ex2;public class CarMain public static void main(String args) ElectricCar electricCar = new ElectricCar();electricCar.move();electricCar.charge();GasCar gasCar = new GasCar();gasCar.move();gasCar.fillUp();```**실행 결과**```차를 이동합니다.충전합니다.차를 이동합니다.기름을 주유합니다.```실행 결과는 기존 예제와 완전히 동일하다.**상속 구조도**전기차와 가솔린차가 `Car`를 상속 받은 덕분에 `electricCar.move() `, `gasCar.move() `를 사용할 수 있다.참고로 당연한 이야기지만 상속은 부모의 기능을 자식이 물려 받는 것이다. 따라서 자식이 부모의 기능을 물려 받아서사용할 수 있다. 반대로 부모 클래스는 자식 클래스에 접근할 수 없다. 자식 클래스는 부모 클래스의 기능을 물려 받기때문에 접근할 수 있지만, 그 반대는 아니다. 부모 코드를 보자! 자식에 대한 정보가 하나도 없다. 반면에 자식 코드는`extends Car `를 통해서 부모를 알고 있다.단일 상속참고로 자바는 다중 상속을 지원하지 않는다. 그래서 `extend ` 대상은 하나만 선택할 수 있다. 부모를 하나만 선택할 수 있다는 뜻이다. 물론 부모가 또 다른 부모를 하나 가지는 것은 괜찮다.**다중 상속 그림**만약 비행기와 자동차를 상속 받아서 하늘을 나는 자동차를 만든다고 가정해보자. 만약 그림과 같이 다중 상속을 사용하게 되면 `AirplaneCar ` 입장에서 `move() `를 호출할 때 어떤 부모의 `move() `를 사용해야 할지 애매한 문제가 발생한다. 이것을 다이아몬드 문제라 한다. 그리고 다중 상속을 사용하면 클래스 계층 구조가 매우 복잡해지 수 있다. 이런문제점 때문에 자바는 클래스의 다중 상속을 허용하지 않는다. 대신에 이후에 설명한 인터페이스의 다중 구현을 허용해서 이러한 문제를 피한다.상속과 메모리 구조**이 부분을 제대로 이해하는 것이 앞으로 정말 중요하다!**상속 관계를 객체로 생성할 때 메모리 구조를 확인해보자.```javaElectricCar electricCar = new ElectricCar();```

    2024.05.11 / 30pages ( 대학레포트 > 시험/강의/학업)

    태그 코드 클래스 , 기능 부모 , 9 상속
  • img
  • 10 다형성1
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편10. 다형성1#1.인강/0.자바/2.자바-기본/다형성 시작/다형성과 캐스팅/캐스팅의 종류/다운캐스팅과 주의점/instanceof/다형성과 메서드 오버라이딩/정리다형성 시작객체지향 프로그래밍의 대표적인 특징으로는 캡슐화, 상속, 다형성이 있다. 그 중에서 다형성은 객체지향 프로그래밍의꽃이라 불린다.앞서 학습한 캡슐화나 상속은 직관적으로 이해하기 쉽다. 반면에 다형성은 제대로 이해하기도 어렵고, 잘 활용하기는 더어렵다. 하지만 좋은 개발자가 되기 위해서는 다형성에 대한 이해가 필수다.다형성(Polymorphism)은 이름 그대로 다양한 형태, 여러 형태를 를 뜻한다.프로그래밍에서 다형성은 한 객체가 여러 타입의 객체로 취급될 수 있는 능력을 뜻한다. 보통 하나의 객체는 하나의 타입으로 고정되어 있다. 그런데 다형성을 사용하면 하나의 객체가 다른 타입으로 사용될 수 있다는 뜻이다. 지금은 이 내용을 이해하기 보다는 참고만 해두자.이제부터 본격적으로 다형성을 학습해보자.다형성을 이해하기 위해서는 크게 2가지 핵심 이론을 알아야 한다.**다형적 참조****메서드 오버라이딩**먼저 다형적 참조라 불리는 개념에 대해 알아보자.다형적 참조다형적 참조를 이해하기 위해 다음과 같은 간단한 상속 관계를 코드로 만들어보자.부모와 자식이 있고, 각각 다른 메서드를 가진다.```javapackage poly.basic;public class Parent public void parentMethod() System.out.println(Parent.parentMethod);```javapackage poly.basic;public class Child extends Parent public void childMethod() System.out.println(Child.childMethod);```javapackage poly.basic;/*** 다형적 참조: 부모는 자식을 품을 수 있다.*/public class PolyMain public static void main(String args) //부모 변수가 부모 인스턴스 참조System.out.println(Parent -> Parent);Parent parent = new Parent();parent.parentMethod();//자식 변수가 자식 인스턴스 참조System.out.println(Child -> Child);Child child = new Child();child.parentMethod();child.childMethod();//부모 변수가 자식 인스턴스 참조(다형적 참조)System.out.println(Parent -> Child);Parent poly = new Child();poly.parentMethod();//Child child1 = new Parent(); 자식은 부모를 담을 수 없다.//자식의 기능은 호출할 수 없다. 컴파일 오류 발생//poly.childMethod();```**실행 결과**```Parent -> ParentParent.parentMethodChild -> ChildParent.parentMethodChild.childMethodParent -> ChildParent.parentMethod```그림을 통해 코드를 하나씩 분석해보자.**부모 타입의 변수가 부모 인스턴스 참조****Parent Parent: parent.parentMethod()**부모 타입의 변수가 부모 인스턴스를 참조한다.`Parent parent = new Parent() ``Parent ` 인스턴스를 만들었다. 이 경우 부모 타입인 `Parent `를 생성했기 때문에 메모리 상에 `Parent `만 생성된다.(자식은 생성되지 않는다.)생성된 참조값을 `Parent ` 타입의 변수인 `parent `에 담아둔다.`parent.parentMethod() `를 호출하면 인스턴스의 `Parent ` 클래스에 있는 `parentMethod() `가 호출된다.**자식 타입의 변수가 자식 인스턴스 참조****Child Child: child.childMethod()**자식 타입의 변수가 자식 인스턴스를 참조한다.`Child child = new Child() ``Child ` 인스턴스를 만들었다. 이 경우 자식 타입인 `Child `를 생성했기 때문에 메모리 상에 `Child `와`Parent `가 모두 생성된다.생성된 참조값을 `Child ` 타입의 변수인 `child `에 담아둔다.`child.childMethod() `를 호출하면 인스턴스의 `Child ` 클래스에 있는 `childMethod() `가 호출된다.여기까지는 지금까지 배운 내용이므로 이해하는데 어려움은 없을 것이다. 이제부터가 중요하다.**다형적 참조: 부모 타입의 변수가 자식 인스턴스 참조****Parent Child: poly.parentMethod()**부모 타입의 변수가 자식 인스턴스를 참조한다.`Parent poly = new Child() ``Child ` 인스턴스를 만들었다. 이 경우 자식 타입인 `Child `를 생성했기 때문에 메모리 상에 `Child `와`Parent `가 모두 생성된다.생성된 참조값을 `Parent ` 타입의 변수인 `poly `에 담아둔다.**부모는 자식을 담을 수 있다.**부모 타입은 자식 타입을 담을 수 있다.`Parent poly `는 부모 타입이다. `new Child() `를 통해 생성된 결과는 `Child ` 타입이다. 자바에서 부모 타입은 자식 타입을 담을 수 있다!`Parent poly = new Child() `: 성공반대로 자식 타입은 부모 타입을 담을 수 없다.`Child child1 = new Parent() `: 컴파일 오류 발생**다형적 참조**지금까지 학습한 내용을 떠올려보면 항상 같은 타입에 참조를 대입했다. 그래서 보통 한 가지 형태만 참조할 수 있다.`Parent parent = new Parent() ``Child child = new Child() `그런데 `Parent ` 타입의 변수는 다음과 같이 자신인 `Parent `는 물론이고, 자식 타입까지 참조할 수 있다. 만약 손자가있다면 손자도 그 하위 타입도 참조할 수 있다.`Parent poly = new Parent() ``Parent poly = new Child() ``Parent poly = new Grandson() `: `Child ` 하위에 손자가 있다면 가능자바에서 부모 타입은 자신은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다. 이것이 바로 다양한 형태를참조할 수 있다고 해서 다형적 참조라 한다.

    2024.05.11 / 23pages ( 대학레포트 > 시험/강의/학업)

    태그 다형적 다형성 , 참조 부모 , 10 다형성1
  • img
  • 11 다형성2
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편11. 다형성2#1.인강/0.자바/2.자바-기본/다형성 활용1/다형성 활용2/다형성 활용3/추상 클래스1/추상 클래스2/인터페이스/인터페이스 - 다중 구현/클래스와 인터페이스 활용/정리다형성 활용1지금까지 학습한 다형성을 왜 사용하는지, 그 장점을 알아보기 위해 우선 다형성을 사용하지 않고 프로그램을 개발한 다음에 다형성을 사용하도록 코드를 변경해보자.아주 단순하고 전통적인 동물 소리 문제로 접근해보자.개, 고양이, 소의 울음 소리를 테스트하는 프로그램을 작성해보자. 먼저 다형성을 사용하지 않고 코드를 작성해보자.**참고**: `Caw`는 오타입니다. 대신에 `Cow`로 정정해야 맞습니다. 강의 내용과 영상 전반에 `Cow`를 너무 많이 사용해서, 고치면 코드를 따라갈 때 혼란스러울 수 있어서, 오타이지만 부득이하게 `Caw`로 유지하겠습니다.예제1```javapackage poly.ex1;public class Dog public void sound() System.out.println(멍멍);```javapackage poly.ex1;public class Cat public void sound() System.out.println(냐옹);```javapackage poly.ex1;public class Caw public void sound() System.out.println(음매);```javapackage poly.ex1;public class AnimalSoundMain public static void main(String args) Dog dog = new Dog();Cat cat = new Cat();Caw caw = new Caw();System.out.println(동물 소리 테스트 시작);dog.sound();System.out.println(동물 소리 테스트 종료);System.out.println(동물 소리 테스트 시작);cat.sound();System.out.println(동물 소리 테스트 종료);System.out.println(동물 소리 테스트 시작);caw.sound();System.out.println(동물 소리 테스트 종료);```**실행 결과**```동물 소리 테스트 시작멍멍동물 소리 테스트 종료동물 소리 테스트 시작냐옹동물 소리 테스트 종료동물 소리 테스트 시작음매동물 소리 테스트 종료```단순히 개, 고양이, 소 동물들의 울음 소리를 출력하는 프로그램이다. 만약 여기서 새로운 동물이 추가되면 어떻게 될까?만약 기존 코드에 소가 없었다고 가정해보자, 소가 추가된다고 가정하면 `Caw` 클래스를 만들고 다음 코드도 추가해야한다.```java//Caw를 생성하는 코드Caw caw = new Caw();//Caw를 사용하는 코드System.out.println(동물 소리 테스트 시작);caw.sound();System.out.println(동물 소리 테스트 종료);````Caw`를 생성하는 부분은 당연히 필요하니 크게 상관이 없지만, `Dog`, `Cat`, `Caw`를 사용해서 출력하는 부분은 계속 중복이 증가한다.**중복 코드**```javaSystem.out.println(동물 소리 테스트 시작);dog.sound();System.out.println(동물 소리 테스트 종료);System.out.println(동물 소리 테스트 시작);cat.sound();System.out.println(동물 소리 테스트 종료);.```이 부분의 중복을 제거할 수 있을까?중복을 제거하기 위해서는 메서드를 사용하거나, 또는 배열과 `for`문을 사용하면 된다.그런데 `Dog`, `Cat`, `Caw`는 서로 완전히 다른 클래스다.중복 제거 시도**메서드로 중복 제거 시도**메서드를 사용하면 다음과 같이 매개변수의 클래스를 `Caw`, `Dog`, `Cat`중에 하나로 정해야 한다.```javaprivate static void soundCaw(Caw caw) System.out.println(동물 소리 테스트 시작);caw.sound();System.out.println(동물 소리 테스트 종료);```따라서 이 메서드는 `Caw` 전용 메서드가 되고 `Dog`, `Cat`은 인수로 사용할 수 없다.`Dog`, `Cat`, `Caw`의 타입(클래스)이 서로 다르기 때문에 `soundCaw ` 메서드를 함께 사용하는 것은 불가능하다.**배열과 for문을 통한 중복 제거 시도**```javaCaw cawArr = cat, dog, caw; //컴파일 오류 발생!System.out.println(동물 소리 테스트 시작);for (Caw caw : cawArr) cawArr.sound();System.out.println(동물 소리 테스트 종료);```배열과 for문 사용해서 중복을 제거하려고 해도 배열의 타입을 `Dog`, `Cat`, `Caw` 중에 하나로 지정해야 한다. 같은`Caw`들을 배열에 담아서 처리하는 것은 가능하지만 타입이 서로 다른 `Dog`, `Cat`, `Caw`을 하나의 배열에 담는 것은 불가능하다.결과적으로 지금 상황에서는 해결 방법이 없다. 새로운 동물이 추가될 때 마다 더 많은 중복 코드를 작성해야 한다.지금까지 설명한 모든 중복 제거 시도가 `Dog`, `Cat`, `Caw`의 타입이 서로 다르기 때문에 불가능하다. **문제의 핵심은 바로 타입이 다르다는 점**이다. 반대로 이야기하면 `Dog`, `Cat`, `Caw`가 모두 같은 타입을 사용할 수 있는 방법이 있다면메서드와 배열을 활용해서 코드의 중복을 제거할 수 있다는 것이다.다형성의 핵심은 다형적 참조와 메서드 오버라이딩이다. 이 둘을 활용하면 `Dog`, `Cat`, `Caw`가 모두 같은 타입을 사용하고, 각자 자신의 메서드도 호출할 수 있다.다형성 활용2이번에는 앞서 설명한 예제를 다형성을 사용하도록 변경해보자.예제2다형성을 사용하기 위해 여기서는 상속 관계를 사용한다. `Animal `(동물) 이라는 부모 클래스를 만들고 `sound() ` 메서드를 정의한다. 이 메서드는 자식 클래스에서 오버라이딩 할 목적으로 만들었다.`Dog`, `Cat`, `Caw`는 `Animal ` 클래스를 상속받았다. 그리고 각각 부모의 `sound() ` 메서드를 오버라이딩 한다.기존 코드를 유지하기 위해 새로운 패키지를 만들고 새로 코드를 작성하자.**주의! 패키지 이름에 주의하자 `import `를 사용해서 다른 패키지에 있는 같은 이름의 클래스를 사용하면 안된다.**```javapackage poly.ex2;public class Animal public void sound() System.out.println(동물 울음 소리);```javapackage poly.ex2;public class Dog extends Animal @Overridepublic void sound() System.out.println(멍멍);```javapackage poly.ex2;public class Cat extends Animal @Overridepublic void sound() System.out.println(냐옹);```javapackage poly.ex2;public class Caw extends Animal@Overridepublic void sound() System.out.println(음매);```javapackage poly.ex2;public class AnimalPolyMain1 public static void main(String args) Dog dog = new Dog();Cat cat = new Cat();Caw caw = new Caw();soundAnimal(dog);soundAnimal(cat);soundAnimal(caw);//동물이 추가 되어도 변하지 않는 코드private static void soundAnimal(Animal animal) System.out.println(동물 소리 테스트 시작);animal.sound();System.out.println(동물 소리 테스트 종료);```**실행 결과**```동물 소리 테스트 시작멍멍동물 소리 테스트 종료동물 소리 테스트 시작냐옹동물 소리 테스트 종료동물 소리 테스트 시작음매동물 소리 테스트 종료```실행 결과는 기존 코드와 같다.**코드를 분석해보자.**`soundAnimal(dog) `을 호출하면`soundAnimal(Animal animal) `에 `Dog` 인스턴스가 전달된다.`Animal animal = dog `로 이해하면 된다. 부모는 자식을 담을 수 있다. `Animal `은 `Dog`의 부모다.메서드 안에서 `animal.sound() ` 메서드를 호출한다.`animal ` 변수의 타입은 `Animal `이므로 `Dog` 인스턴스에 있는 `Animal ` 클래스 부분을 찾아서 `sound() ` 메서드를 실행한다. 그런데 하위 클래스인 `Dog`에서 `sound() ` 메서드를 오버라이딩 했다. 따라서 오버라이딩한메서드가 우선권을 가진다.`Dog` 클래스에 있는 `sound() ` 메서드가 호출되므로 멍멍이 출력된다.이 코드의 핵심은 `Animal animal ` 부분이다.**다형적 참조** 덕분에 `animal ` 변수는 자식인 `Dog`, `Cat`, `Caw`의 인스턴스를 참조할 수 있다. (부모는 자식을 담

    2024.05.11 / 35pages ( 대학레포트 > 시험/강의/학업)

    태그 다형성 동물 , 테스트 소리 , 11 다형성2
  • img
  • 12 다형성과 설계
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편12. 다형성과 설계#1.인강/0.자바/2.자바-기본/좋은 객체 지향 프로그래밍이란?/다형성 - 역할과 구현 예제1/다형성 - 역할과 구현 예제2/다형성 - 역할과 구현 예제3/OCP(Open-Closed Principle) 원칙/문제와 풀이/정리좋은 객체 지향 프로그래밍이란? 다형성 - 역할과 구현 예제1앞서 설명한 내용을 더 깊이있게 이해하기 위해, 간단한 운전자와 자동차의 관계를 개발해보자. 먼저 다형성을 사용하지않고, 역할과 구현을 분리하지 않고 단순하게 개발해보자.`Driver `는 `K3Car `를 운전하는 프로그램이다.```javapackage poly.car0;public class K3Car public void startEngine() System.out.println(K3Car.startEngine);public void offEngine() System.out.println(K3Car.offEngine);public void pressAccelerator() System.out.println(K3Car.pressAccelerator);```javapackage poly.car0;public class Driver private K3Car k3Car;public void setK3Car(K3Car k3Car) this.k3Car = k3Car;public void drive() System.out.println(자동차를 운전합니다.);k3Car.startEngine();k3Car.pressAccelerator();k3Car.offEngine();```javapackage poly.car0;public class CarMain0 public static void main(String args) Driver driver = new Driver();K3Car k3Car = new K3Car();driver.setK3Car(k3Car);driver.drive();````Driver `와 `K3Car `를 먼저 생성한다. 그리고 `driver.setK3Car() `를 통해 `driver `에게 `k3Car `의 참조를 넘겨준다.`driver.driver() `를 호출한다.**실행 결과**```자동차를 운전합니다.K3Car.startEngineK3Car.pressAcceleratorK3Car.offEngine```**메모리 그림** 다형성 - 역할과 구현 예제2새로운 Model3 차량을 추가해야 하는 요구사항이 들어왔다. 이 요구사항을 맞추려면 기존에 `Driver ` 코드를 많이 변경해야 한다.드라이버는 `K3Car `도 운전할 수 있고, `Model3Car `도 운전할 줄 있어야 한다. 참고로 둘을 동시에 운전하는 것은 아니다.```javapackage poly.car0;public class Model3Car public void startEngine() System.out.println(Model3Car.startEngine);public void offEngine() System.out.println(Model3Car.offEngine);public void pressAccelerator() System.out.println(Model3Car.pressAccelerator);```**Driver - 코드 변경**```javapackage poly.car0;public class Driver private K3Car k3Car;

    2024.05.11 / 31pages ( 대학레포트 > 시험/강의/학업)

    태그 역할 다형성 , 코드 구현 , 12 다형성과 설계
  • img
  • 13 다음으로
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편13. 다음으로#1.인강/0.자바/2.자바-기본학습 내용 정리전체 목차1. 클래스와 데이터/프로젝트 환경 구성/클래스가 필요한 이유/클래스 도입/객체 사용/클래스, 객체, 인스턴스 정리/배열 도입 - 시작/배열 도입 - 리펙토링/문제와 풀이/정리2. 기본형과 참조형/기본형 vs 참조형1 - 시작/기본형 vs 참조형2 - 변수 대입/기본형 vs 참조형3 - 메서드 호출/참조형과 메서드 호출 - 활용/변수와 초기화/null/NullPointerException/문제와 풀이/정리3. 객체 지향 프로그래밍/절차 지향 프로그래밍1 - 시작/절차 지향 프로그래밍2 - 데이터 묶음/절차 지향 프로그래밍3 - 메서드 추출/클래스와 메서드/객체 지향 프로그래밍/문제와 풀이/정리4. 생성자/생성자 - 필요한 이유/this/생성자 - 도입/기본 생성자/생성자 - 오버로딩과 this()/문제와 풀이/정리5. 패키지/패키지 - 시작/패키지 - import /패키지 규칙/패키지 활용/정리6. 접근 제어자/접근 제어자 이해1/접근 제어자 이해2/접근 제어자 종류/접근 제어자 사용 - 필드, 메서드/접근 제어자 사용 - 클래스 레벨/캡슐화/문제와 풀이/정리7. 자바 메모리 구조와 static/자바 메모리 구조/스택과 큐 자료 구조/스택 영역/스택 영역과 힙 영역/static 변수1/static 변수2/static 변수3/static 메서드1/static 메서드2/static 메서드3/문제와 풀이/정리8. final/final 변수와 상수1/final 변수와 상수2/final 변수와 참조/정리9. 상속/상속 - 시작/상속 관계/상속과 메모리 구조/상속과 기능 추가/상속과 메서드 오버라이딩/상속과 접근 제어/super - 부모 참조/super - 생성자/문제와 풀이/정리10. 다형성1/다형성 시작/다형성과 캐스팅/캐스팅의 종류/다운캐스팅과 주의점/instanceof/다형성과 메서드 오버라이딩/정리11. 다형성2/다형성 활용1/다형성 활용2/다형성 활용3/추상 클래스1/추상 클래스2/인터페이스/인터페이스 - 다중 구현/클래스와 인터페이스 활용/정리12. 다형성과 설계/좋은 객체 지향 프로그래밍이란?/다형성 - 역할과 구현 예제1/다형성 - 역할과 구현 예제2/다형성 - 역할과 구현 예제3/OCP(Open-Closed Principle) 원칙/문제와 풀이/정리

    2024.05.11 / 7pages ( 대학레포트 > 시험/강의/학업)

    태그 메서드 자바 , 정리 다형성 , 13 다음으로
  • img
  • 1 클래스와 데이터
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편1. 클래스와 데이터#1.인강/0.자바/2.자바-기본/프로젝트 환경 구성/클래스가 필요한 이유/클래스 도입/객체 사용/클래스, 객체, 인스턴스 정리/배열 도입 - 시작/배열 도입 - 리펙토링/문제와 풀이/정리프로젝트 환경 구성자바 입문편에서 인텔리제이 설치, 선택 이유 설명프로젝트 환경 구성에 대한 자세한 내용은 자바 입문편 참고여기서는 입문편을 들었다는 가정하에 자바 기본편 설정 진행인텔리제이 실행하기**New Project**New Project를 선택해서 새로운 프로젝트를 만들자**New Project 화면**Name:자바 입문편 강의: java-start자바 기본편 강의: **java-basic**Location: 프로젝트 위치, 임의 선택Create Git repository 선택하지 않음Language: JavaBuild system: IntelliJJDK: 자바 버전 17 이상`Add sample code ` 선택**JDK 다운로드 화면 이동 방법**자바로 개발하기 위해서는 JDK가 필요하다. JDK는 자바 프로그래머를 위한 도구 + 자바 실행 프로그램의 묶음이다.**Name:**자바 입문편 강의: java-start자바 기본편 강의: **java-basic****JDK 다운로드 화면**Version: 21을 선택하자.Vendor: Oracle OpenJDK를 선택하자. 다른 것을 선택해도 된다.aarch64: 애플 M1, M2, M3 CPU 사용시 선택, 나머지는 뒤에 이런 코드가 붙지 않은 JDK를 선택하면 된다.Location: JDK 설치 위치, 기본값을 사용하자.**주의 - 변경 사항****Oracle OpenJDK 21 버전이 목록에 없다면 Eclipse Temurin 21을 선택하면 된다.**`Download ` 버튼을 통해서 다운로드 JDK를 다운로드 받는다.다운로드가 완료 되고 이전 화면으로 돌아가면 `Create ` 버튼 선택하자. 그러면 다음 IntelliJ 메인 화면으로 넘어간다.**IntelliJ 메인 화면**앞서 `Add sample code ` 선택해서 샘플 코드가 만들어져 있다.위쪽에 빨간색으로 강조한 초록색 화살표 버튼을 선택하고 `Run Main.main() ` 버튼을 선택하면 프로그램이실행된다.윈도우 사용자 추가 설명서윈도우 사용자도 Mac용 IntelliJ와 대부분 같은 화면이다. 일부 다른 화면 위주로 설명하겠다.프로그램 시작 화면New Project 선택**New Project 화면****Name:**자바 입문편 강의: java-start자바 기본편 강의: **java-basic**Location: 프로젝트 위치, 임의 선택Create Git repository 선택하지 않음Language: JavaBuild system: IntelliJJDK: 자바 버전 17 이상`Add sample code ` 선택JDK 설치는 Mac과 동일하다.Version: 21Vendor: Oracle OpenJDKLocation은 가급적 변경하지 말자.

    2024.05.11 / 35pages ( 대학레포트 > 시험/강의/학업)

    태그 강의 자바 , 화면 클래스 , 1 클래스와 데이터
  • img
  • 2 기본형과 참조형
  • 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편 김영한의 실전 자바 기본편2. 기본형과 참조형#1.인강/0.자바/2.자바-기본/기본형 vs 참조형1 - 시작/기본형 vs 참조형2 - 변수 대입/기본형 vs 참조형3 - 메서드 호출/참조형과 메서드 호출 - 활용/변수와 초기화/null/NullPointerException/문제와 풀이/정리기본형 vs 참조형1 - 시작**자바에서 참조형을 제대로 이해하는 것은 정말 중요하다.**지금까지 기본형과 참조형에 대해서 조금씩 보았다. 이번에는 기본형과 참조형에 대해서 더 깊이있게 알아보고 확실하게 정리해보자.변수의 데이터 타입을 가장 크게 보면 기본형과 참조형으로 분류할 수 있다. 사용하는 값을 변수에 직접 넣을 수 있는 기본형, 그리고 이전에 본 `Student student1 `과 같이 객체가 저장된 메모리의 위치를 가리키는 참조값을 넣을 수 있는 참조형으로 분류할 수 있다.기본형(Primitive Type): `int`, `long `, `double `, `boolean `처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형이라 한다.참조형(Reference Type): `Student student1 `, `int students `와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형이라 한다. 참조형은 객체 또는 배열에 사용된다.쉽게 이야기해서 기본형 변수에는 직접 사용할 수 있는 값이 들어있지만 참조형 변수에는 위치(참조값)가 들어가 있다.참조형 변수를 통해서 뭔가 하려면 결국 참조값을 통해 해당 위치로 이동해야 한다.**기본형 vs 참조형 - 기본**기본형은 숫자 `10`, `20`과 같이 실제 사용하는 값을 변수에 담을 수 있다. 그래서 해당 값을 바로 사용할 수 있다.참조형은 실제 사용하는 값을 변수에 담는 것이 아니다. 이름 그대로 실제 객체의 위치(참조, 주소)를 저장한다. 참조형에는 객체와 배열이 있다.객체는 `.`(dot)을 통해서 메모리 상에 생성된 객체를 찾아가야 사용할 수 있다.배열은 ``를 통해서 메모리 상에 생성된 배열을 찾아가야 사용할 수 있다.**기본형 vs 참조형 - 계산**기본형은 들어있는 값을 그대로 계산에 사용할 수 있다.예) 더하고 빼고, 사용하고 등등, (숫자 같은 것들은 바로 계산할 수 있음)참조형은 들어있는 참조값을 그대로 사용할 수 없다. 주소지만 가지고는 할 수 있는게 없다. 주소지에 가야 실체가있다!예) 더하고 빼고 사용하고 못함! 참조값만 가지고는 계산 할 수 있는 것이 없음!기본형은 연산이 가능하지만 참조형은 연산이 불가능하다.```javaint a = 10, b = 20;int sum = a + b;```기본형은 변수에 실제 사용하는 값이 담겨있다. 따라서 `+`, `-`와 같은 연산이 가능하다.```javaStudent s1 = new Student();Student s2 = new Student();s1 + s2 //오류 발생```참조형은 변수에 객체의 위치인 참조값이 들어있다. 참조값은 계산에 사용할 수 없다. 따라서 오류가 발생한다.물론 다음과 같이 `.`을 통해 객체의 기본형 멤버 변수에 접근한 경우에는 연산을 할 수 있다.```javaStudent s1 = new Student();s1.grade = 100;Student s2 = new Student();s2.grade = 90;int sum = s1.grade + s2.grade; //연산 가능```**쉽게 이해하는 팁**기본형을 제외한 나머지는 모두 참조형이다.기본형은 소문자로 시작한다. `int`, `long `, `double `, `boolean ` 모두 소문자로 시작한다.기본형은 자바가 기본으로 제공하는 데이터 타입이다. 이러한 기본형은 개발자가 새로 정의할 수 없다. 개발자는 참조형인 클래스만 직접 정의할 수 있다.클래스는 대문자로 시작한다. `Student `클래스는 모두 참조형이다.**참고 - String**자바에서 `String `은 특별하다. `String `은 사실은 클래스다. 따라서 참조형이다. 그런데 기본형처럼 문자 값을 바로대입할 수 있다. 문자는 매우 자주 다루기 때문에 자바에서 특별하게 편의 기능을 제공한다. `String `에 대한 자세한 내용은 뒤에서 설명한다.기본형 vs 참조형2 - 변수 대입**대원칙: 자바는 항상 변수의 값을 복사해서 대입한다.**자바에서 변수에 값을 대입하는 것은 변수에 들어 있는 값을 복사해서 대입하는 것이다.기본형, 참조형 모두 항상 변수에 있는 값을 복사해서 대입한다. 기본형이면 변수에 들어 있는 실제 사용하는 값을 복사해서 대입하고, 참조형이면 변수에 들어 있는 참조값을 복사해서 대입한다.이 대원칙을 이해하면 복잡한 상황에도 코드를 단순하게 이해할 수 있다.**기본형 대입**```javaint a = 10;int b = a;```**참조형 대입**```javaStudent s1 = new Student();Student s2 = s1;```기본형은 변수에 값을 대입하더라도 실제 사용하는 값이 변수에 바로 들어있기 때문에 해당 값만 복사해서 대입한다고생각하면 쉽게 이해할 수 있다. 그런데 **참조형의 경우 실제 사용하는 객체가 아니라 객체의 위치를 가리키는 참조값만복사**된다. 쉽게 이야기해서 실제 건물이 복사가 되는 것이 아니라 건물의 위치인 주소만 복사되는 것이다. 따라서 같은건물을 찾아갈 수 있는 방법이 하나 늘어날 뿐이다.구체적인 예시를 통해서 변수 대입시 기본형과 참조형의 차이를 알아보자.기본형과 변수 대입다음 코드를 보고 어떤 결과가 나올지 먼저 생각해보자. 너무 쉽고 당연한 내용이지만, 이후에 나올 참조형과 비교를 위해서 다시 한번 정리해보자.**VarChange1**```javapackage ref;public class VarChange1 public static void main(String args) int a = 10;int b = a;System.out.println(a = + a);System.out.println(b = + b);//a 변경a = 20;System.out.println(변경 a = 20);System.out.println(a = + a);System.out.println(b = + b);//b 변경b = 30;System.out.println(변경 b = 30);System.out.println(a = + a);System.out.println(b = + b);```**실행 결과**```a = 10b = 10변경 a = 20a = 20b = 10변경 b = 30a = 20b = 30```그림을 통해 자세히 알아보자.**int a = 10****int b = a****실행 결과**```a = 10b = 10```변수의 대입은 변수에 들어있는 값을 복사해서 대입한다. 여기서는 변수 `a`에 들어있는 값 `10`을 복사해서 변수 `b`에대입한다. 변수 `a` 자체를 `b`에 대입하는 것이 아니다!**a = 20****실행 결과**```a = 10b = 20```변수 `a`에 값 `20`을 대입했다. 따라서 변수 `a`의 값이 `10`에서 `20`으로 변경되었다. 당연한 이야기지만 변수 `b`에는 아무런 영향을 주지 않는다.**b = 30****실행 결과**```a = 20b = 30```변수 `b`에 값 `30`을 대입했다. 변수 `b`의 값이 `10`에서 `30`으로 변경되었다. 당연한 이야기지만 변수 `a`에는 아무런 영향을 주지 않는다.**최종 결과**여기서 핵심은 `int b = a `라고 했을 때 변수에 들어있는 값을 복사해서 전달한다는 점이다. 따라서 `a=20 `, `b=30 `이라고 했을 때 각각 본인의 값만 변경되는 것을 확인할 수 있다.너무 당연한 이야기를 왜 이렇게 장황하게 풀어서 하지? 라고 생각한다면 이제 진짜 문제를 만나보자.참조형과 변수 대입참조형 예시를 위해 `Data ` 클래스를 하나 만들자. 이 클래스는 단순히 `int value `라는 멤버 변수를 하나 가진다.**Data**```javapackage ref;public class Data int value;```다음 코드를 보고 어떤 결과가 나올지 먼저 생각해보자. 꼭 먼저 생각해보고 이후에 실행해서 정답을 맞춰보자.**VarChange2**```javapackage ref;public class VarChange2 public static void main(String args) Data dataA = new Data();dataA.value = 10;Data dataB = dataA;System.out.println(dataA 참조값= + dataA);System.out.println(dataB 참조값= + dataB);System.out.println(dataA.value = + dataA.value);System.out.println(dataB.value = + dataB.value);//dataA 변경dataA.value = 20;System.out.println(변경 dataA.value = 20);System.out.println(dataA.value = + dataA.value);System.out.println(dataB.value = + dataB.value);//dataB 변경dataB.value = 30;System.out.println(변경 dataB.value = 30);System.out.println(dataA.value = + dataA.value);System.out.println(dataB.value = + dataB.value);```**실행 결과**```dataA 참조값=ref.Data@x001dataB 참조값=ref

    2024.05.11 / 35pages ( 대학레포트 > 시험/강의/학업)

    태그 참조값 변수 , 참조 기본형 , 2 기본형과 참조형
  • img
  • 3 String 클래스
  • 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편3. String 클래스#1.인강/0.자바/3.자바-중급1편/String 클래스 - 기본/String 클래스 - 비교/String 클래스 - 불변 객체/String 클래스 - 주요 메서드1/String 클래스 - 주요 메서드2/StringBuilder - 가변 String/String 최적화/메서드 체인닝 - Method Chaining/문제와 풀이1/문제와 풀이2/정리String 클래스 - 기본자바에서 문자를 다루는 대표적인 타입은 `char `, `String ` 2가지가 있다.```javapackage lang.string;public class CharArrayMain public static void main(String args) char charArr = new charh, e, l, l, o;System.out.println(charArr);String str = hello;System.out.println(str = + str);```**실행 결과**```hellostr = hello```기본형인 `char `는 문자 하나를 다룰 때 사용한다. `char `를 사용해서 여러 문자를 나열하려면 `char `을 사용해야 한다. 하지만 이렇게 `char `을 직접 다루는 방법은 매우 불편하기 때문에 자바는 문자열을 매우 편리하게 다룰 수 있는`String ` 클래스를 제공한다.`String ` 클래스를 통해 문자열을 생성하는 방법은 2가지가 있다.```javapackage lang.string;public class StringBasicMain public static void main(String args) String str1 = hello;String str2 = new String(hello);System.out.println(str1 = + str1);System.out.println(str2 = + str2);```쌍따옴표 사용: `hello `객체 생성: `new String(hello); ``String `은 클래스다. `int`, `boolean ` 같은 기본형이 아니라 참조형이다. 따라서 `str1 ` 변수에는 `String ` 인스턴스의 참조값만 들어갈 수 있다. 따라서 다음 코드는 뭔가 어색하다.```javaString str1 = hello;```문자열은 매우 자주 사용된다. 그래서 편의상 쌍따옴표로 문자열을 감싸면 자바 언어에서 `new String(hello) `와 같이 변경해준다. (이 경우 실제로는 성능 최적화를 위해 문자열 풀을 사용하는데, 이 부분은 뒤에서 설명한다.)```javaString str1 = hello; //기존String str1 = new String(hello); //변경```String 클래스 구조`String ` 클래스는 대략 다음과 같이 생겼다.```javapublic final class String //문자열 보관private final char value;// 자바 9 이전private final byte value;// 자바 9 이후//여러 메서드public String concat(String str) .public int length() ..```클래스이므로 속성과 기능을 가진다.**속성(필드)**```javaprivate final char value;```여기에는 `String `의 실제 문자열 값이 보관된다. 문자 데이터 자체는 `char `에 보관된다.`String ` 클래스는 개발자가 직접 다루기 불편한 `char `을 내부에 감추고 `String ` 클래스를 사용하는 개발자가 편리하게 문자열을 다룰 수 있는 수 있도록 다양한 기능을 제공한다. 그리고 메서드 제공을 넘어서 자바 언어 차원에서도여러 편의 문법을 제공한다.**참고: 자바 9 이후 String 클래스 변경 사항**자바 9부터 `String ` 클래스에서 `char ` 대신에 `byte `을 사용한다.```javaprivate final byte value;```자바에서 문자 하나를 표현하는 `char `는 `2byte `를 차지한다. 그런데 영어, 숫자는 보통 `1byte `로 표현이 가능하다. 그래서 단순 영어, 숫자로만 표현된 경우 `1byte `를 사용하고(정확히는 Latin-1 인코딩의 경우 `1byte ` 사용) , 그렇지 않은 나머지의 경우 `2byte `인 UTF-16 인코딩을 사용한다. 따라서 메모리를 더 효율적으로 사용할수 있게 변경되었다.**기능(메서드)**`String ` 클래스는 문자열로 처리할 수 있는 다양한 기능을 제공한다. 기능이 방대하므로 필요한 기능이 있으면 검색하거나 API 문서를 찾아보자. 주요 메서드는 다음과 같다.`length() `: 문자열의 길이를 반환한다.`charAt(int index) `: 특정 인덱스의 문자를 반환한다.`substring(int beginIndex, int endIndex) `: 문자열의 부분 문자열을 반환한다.`indexOf(String str) `: 특정 문자열이 시작되는 인덱스를 반환한다.`toLowerCase() `, `toUpperCase() `: 문자열을 소문자 또는 대문자로 변환한다.`trim() `: 문자열 양 끝의 공백을 제거한다.`concat(String str) `: 문자열을 더한다.String 클래스와 참조형`String `은 클래스이다. 따라서 기본형이 아니라 참조형이다.참조형은 변수에 계산할 수 있는 값이 들어있는 것이 아니라 `x001 `과 같이 계산할 수 없는 참조값이 들어있다. 따라서원칙적으로 `+` 같은 연산을 사용할 수 없다.```javapackage lang.string;public class StringConcatMain public static void main(String args) String a = hello;String b = java;String result1 = a.concat(b);String result2 = a + b;System.out.println(result1 = + result1);System.out.println(result2 = + result2);```자바에서 문자열을 더할 때는 `String `이 제공하는 `concat() `과 같은 메서드를 사용해야 한다.하지만 문자열은 너무 자주 다루어지기 때문에 자바 언어에서 편의상 특별히 `+` 연산을 제공한다.**실행 결과**```result1 = hello javaresult2 = hello java```String 클래스 - 비교`String ` 클래스 비교할 때는 `` 비교가 아니라 항상 `equals() ` 비교를 해야한다.**동일성(Identity)**: `` 연산자를 사용해서 두 객체의 참조가 동일한 객체를 가리키고 있는지 확인**동등성(Equality) **: `equals() ` 메서드를 사용하여 두 객체가 논리적으로 같은지 확인```javapackage lang.string.equals;public class StringEqualsMain1 public static void main(String args) String str1 = new String(hello);String str2 = new String(hello);System.out.println(new String() 비교: + (str1 str2));System.out.println(new String() equals 비교: + (str1.equals(str2)));String str3 = hello;String str4 = hello;System.out.println(리터럴 비교: + (str3 str4));System.out.println(리터럴 equals 비교: + (str3.equals(str4)));```**실행 결과**```new String() 비교: falsenew String() equals 비교: true리터럴 비교: true리터럴 equals 비교: true```**그림 - new String() 비교**`str1 `과 `str2 `는 `new String() `을 사용해서 각각 인스턴스를 생성했다. 서로 다른 인스턴스이므로 동일성( ``) 비교에 실패한다.둘은 내부에 같은 `hello ` 값을 가지고 있기 때문에 논리적으로 같다. 따라서 동등성( `equals() `) 비교에 성공한다. 참고로 `String ` 클래스는 내부 문자열 값을 비교하도록 `equals() ` 메서드를 재정의 해두었다.**그림 - 문자열 리터럴, 문자열 풀**`String str3 = hello `와 같이 문자열 리터럴을 사용하는 경우 자바는 메모리 효율성과 성능 최적화를 위해 문자열 풀을 사용한다.자바가 실행되는 시점에 클래스에 문자열 리터럴이 있으면 문자열 풀에 `String ` 인스턴스를 미리 만들어둔다.이때 같은 문자열이 있으면 만들지 않는다.`String str3 = hello `와 같이 문자열 리터럴을 사용하면 문자열 풀에서 `hello `라는 문자를 가진`String ` 인스턴스를 찾는다. 그리고 찾은 인스턴스의 참조( `x003 `)를 반환한다.`String str4 = hello `의 경우 `hello ` 문자열 리터럴을 사용하므로 문자열 풀에서 `str3 `과 같은`x003 ` 참조를 사용한다.문자열 풀 덕분에 같은 문자를 사용하는 경우 메모리 사용을 줄이고 문자를 만드는 시간도 줄어들기 때문에 성능도 최적화 할 수 있다.따라서 문자열 리터럴을 사용하는 경우 같은 참조값을 가지므로 `` 비교에 성공한다.**참고**: 풀

    2024.05.11 / 40pages ( 대학레포트 > 시험/강의/학업)

    태그 메서드 클래스 , 자바 문자열 , 3 String 클
  • img
  • 4 래퍼, Class 클래스
  • 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편4. 래퍼, Class 클래스#1.인강/0.자바/3.자바-중급1편/래퍼 클래스 - 기본형의 한계1/래퍼 클래스 - 기본형의 한계2/래퍼 클래스 - 자바 래퍼 클래스/래퍼 클래스 - 오토 박싱/래퍼 클래스 - 주요 메서드와 성능/Class 클래스/System 클래스/Math, Random 클래스/문제와 풀이1/문제와 풀이2/정리래퍼 클래스 - 기본형의 한계1기본형의 한계자바는 객체 지향 언어이다. 그런데 자바 안에 객체가 아닌 것이 있다. 바로 `int`, `double ` 같은 기본형(PrimitiveType)이다.기본형은 객체가 아니기 때문에 다음과 같은 한계가 있다.**객체가 아님**: 기본형 데이터는 객체가 아니기 때문에, 객체 지향 프로그래밍의 장점을 살릴 수 없다. 예를 들어 객체는 유용한 메서드를 제공할 수 있는데, 기본형은 객체가 아니므로 메서드를 제공할 수 없다.추가로 객체 참조가 필요한 컬렉션 프레임워크를 사용할 수 없다. 그리고 제네릭도 사용할 수 없다. (이 부분은 뒤에서 설명한다.)**null 값을 가질 수 없음**: 기본형 데이터 타입은 `null ` 값을 가질 수 없다. 때로는 데이터가 `없음` 이라는 상태를 나타내야 할 필요가 있는데, 기본형은 항상 값을 가지기 때문에 이런 표현을 할 수 없다.기본형의 한계를 이해하기 위해, 두 값을 비교해서 다음과 같은 결과를 출력하는 간단한 코드를 작성해보자.왼쪽의 값이 더 작다 `-1`두 값이 같다 `0`왼쪽의 값이 더 크다 `1````javapackage lang.wrapper;public class MyIntegerMethodMain0 public static void main(String args) int value = 10;int i1 = compareTo(value, 5);int i2 = compareTo(value, 10);int i3 = compareTo(value, 20);System.out.println(i1 = + i1);System.out.println(i2 = + i2);System.out.println(i3 = + i3);public static int compareTo(int value, int target) if (value < target) return -1; else if (value > target) return 1; else return 0;```**실행 결과**```i1 = 1i2 = 0i3 = -1```여기서는 `value `와 비교 대상 값을 `compareTo() `라는 외부 메서드를 사용해서 비교한다. 그런데 자기 자신인`value `와 다른 값을 연산하는 것이기 때문에 항상 자기 자신의 값인 `value `가 사용된다. 이런 경우 만약 `value `가객체라면 `value ` 객체 스스로 자기 자신의 값과 다른 값을 비교하는 메서드를 만드는 것이 더 유용할 것이다.직접 만든 래퍼 클래스`int`를 클래스로 만들어보자. `int`는 클래스가 아니지만, `int` 값을 가지고 클래스를 만들면 된다. 다음 코드는 마치`int`를 클래스로 감싸서 만드는 것 처럼 보인다. 이렇게 특정 기본형을 감싸서(Wrap) 만드는 클래스를 래퍼 클래스(Wrapper class)라 한다.```javapackage lang.wrapper;public class MyInteger private final int value;public MyInteger(int value) this.value = value;public int getValue() return value;public int compareTo(int target) if (value < target) return -1; else if (value > target) return 1; else return 0;@Overridepublic String toString() return String.valueOf(value); //숫자를 문자로 변경````MyInteger `는 `int value `라는 단순한 기본형 변수를 하나 가지고 있다.그리고 이 기본형 변수를 편리하게 사용하도록 다양한 메서드를 제공한다.앞에서 본 `compareTo() ` 메서드를 클래스 내부로 캡슐화 했다.이 클래스는 불변으로 설계했다.`MyInteger ` 클래스는 단순한 데이터 조각인 `int`를 내부에 품고, 메서드를 통해 다양한 기능을 추가했다. 덕분에 데이터 조각에 불과한 `int`를 `MyInteger `를 통해 객체로 다룰 수 있게 되었다.```javapackage lang.wrapper;public class MyIntegerMethodMain1 public static void main(String args) MyInteger myInteger = new MyInteger(10);int i1 = myInteger.compareTo(5);int i2 = myInteger.compareTo(10);int i3 = myInteger.compareTo(20);System.out.println(i1 = + i1);System.out.println(i2 = + i2);System.out.println(i3 = + i3);```**실행 결과**```i1 = 1i2 = 0i3 = -1````myInteger.compareTo() `는 자기 자신의 값을 외부의 값과 비교한다.`MyInteger `는 객체이므로 자신이 가진 메서드를 편리하게 호출할 수 있다.참고로 `int`는 기본형이기 때문에 스스로 메서드를 가질 수 없다.래퍼 클래스 - 기본형의 한계2기본형과 null기본형은 항상 값을 가져야 한다. 하지만 때로는 데이터가 없음이라는 상태가 필요할 수 있다.다음 코드를 작성해보자.```javapackage lang.wrapper;public class MyIntegerNullMain0 public static void main(String args) int intArr = -1, 0, 1, 2, 3;System.out.println(findValue(intArr, -1)); //-1System.out.println(findValue(intArr, 0));System.out.println(findValue(intArr, 1));System.out.println(findValue(intArr, 100)); //-1private static int findValue(int intArr, int target) for (int value : intArr) if (value target) return value;return -1;````findValue() `는 배열에 찾는 값이 있으면 해당 값을 반환하고, **찾는 값이 없으면 `-1`을 반환**한다.`findValue() `는 결과로 `int`를 반환한다. `int`와 같은 기본형은 항상 값이 있어야 한다. 여기서도 값을 반환할 때 값을 찾지 못하면 숫자 중에 하나를 반환해야 하는데 보통 `-1` 또는 `0`을 사용한다.**실행 결과**```-101-1```실행 결과를 보면 입력값이 `-1`일 때 `-1`을 반환한다. 그런데 배열에 없는 값인 `100`을 입력해도 같은 `-1`을 반환한다.입력값이 `-1`일 때를 생각해보면, 배열에 `-1` 값이 있어서 `-1`을 반환한 것인지, 아니면 `-1` 값이 없어서 `-1`을 반환한 것인지 명확하지 않다.객체의 경우 데이터가 없다는 `null `이라는 명확한 값이 존재한다.다음 코드를 작성해보자.```javapackage lang.wrapper;public class MyIntegerNullMain1 public static void main(String args) MyInteger intArr = new MyInteger(-1), new MyInteger(0), newMyInteger(1);System.out.println(findValue(intArr, -1));System.out.println(findValue(intArr, 0));System.out.println(findValue(intArr, 1));System.out.println(findValue(intArr, 100)); //-1private static MyInteger findValue(MyInteger intArr, int target) for (MyInteger myInteger : intArr) if (myInteger.getValue() target) return myInteger;return null;```**실행 결과**```-101null```앞서 만든 `MyInteger ` 래퍼 클래스를 사용했다.실행 결과를 보면 `-1`을 입력했을 때는 `-1`을 반환한다.`100`을 입력했을 때는 값이 없다는 `null `을 반환한다.기본형은 항상 값이 존재해야 한다. 숫자의 경우 `0`, `-1` 같은 값이라도 항상 존재해야 한다. 반면에 객체인 참조형은 값이 없다는 `null `을 사용할 수 있다. 물론 `null ` 값을 반환하는 경우 잘못하면 `NullPointerException `이 발생할수 있기 때문에 주의해서 사용해야 한다.래퍼 클래스 - 자바 래퍼 클래스지금까지 설명한 래퍼 클래스는 기본형을 객체로 감싸서 더 편리하게 사용하도록 도와주기 때문에 상당히 유용하다.쉽게 이야기해서 래퍼 클래스는 기본형의 객체 버전이다.자바는 기본형에 대응하는 래퍼 클래스를 기본으로 제공한다.`byte ` `Byte ``short ` `Short ``int` `Integer ``long ` `Long ``float ` `Flo

    2024.05.11 / 28pages ( 대학레포트 > 시험/강의/학업)

    태그 객체 클래스 , 메서드 기본형 , 4 래퍼, Clas
  • img
  • 5 열거형 - ENUM
  • 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편5. 열거형 - ENUM#1.인강/0.자바/3.자바-중급1편/문자열과 타입 안전성1/문자열과 타입 안전성2/타입 안전 열거형 패턴/열거형 - Enum Type/열거형 - 주요 메서드/열거형 - 리팩토링1/열거형 - 리팩토링2/열거형 - 리팩토링3/문제와 풀이1/문제와 풀이2/정리문자열과 타입 안전성1자바가 제공하는 열거형(Enum Type)을 제대로 이해하려면 먼저 열거형이 생겨난 이유를 알아야 한다. 예제를 순서대로 따라가며 열거형이 만들어진 근본적인 이유를 알아보자.비즈니스 요구사항고객은 3등급으로 나누고, 상품 구매시 등급별로 할인을 적용한다. 할인시 소수점 이하는 버린다.`BASIC ` 10% 할인`GOLD ` 20% 할인`DIAMOND ` 30% 할인예) `GOLD ` 유저가 10000원을 구매하면 할인 대상 금액은 2000원이다.예제를 구현해보자.회원 등급과 가격을 입력하면 할인 금액을 계산해주는 클래스를 만들어보자.예를 들어서 `GOLD `, 10000원을 입력하면 할인 대상 금액인 2000원을 반환한다.```javapackage enumeration.ex0;public class DiscountService public int discount(String grade, int price) int discountPercent = 0;if (grade.equals(BASIC)) discountPercent = 10; else if (grade.equals(GOLD)) discountPercent = 20; else if (grade.equals(DIAMOND)) discountPercent = 30; else System.out.println(grade + : 할인X);return price * discountPercent / 100;````price * discountPercent / 100 `: `가격 * 할인율 / 100 `을 계산하면 할인 금액을 구할 수 있다.회원 등급 외 다른 값이 입력되면 `할인X`를 출력한다. 이 경우 `discountPercent `가 `0`이므로 할인 금액도 `0`원으로 계산된다.예제를 단순화하기 위해 회원 등급에 `null `은 입력되지 않는다고 가정한다.```javapackage enumeration.ex0;public class StringGradeEx01 public static void main(String args) int price = 10000;DiscountService discountService = new DiscountService();int basic = discountService.discount(BASIC, price);int gold = discountService.discount(GOLD, price);int diamond = discountService.discount(DIAMOND, price);System.out.println(BASIC 등급의 할인 금액: + basic);System.out.println(GOLD 등급의 할인 금액: + gold);System.out.println(DIAMOND 등급의 할인 금액: + diamond);```**실행 결과**```BASIC 등급의 할인 금액: 1000GOLD 등급의 할인 금액: 2000DIAMOND 등급의 할인 금액: 3000```실행 결과를 보면 각각의 회원 등급에 맞는 할인이 적용된 것을 확인할 수 있다.그런데 지금과 같이 단순히 문자열을 입력하는 방식은, 오타가 발생하기 쉽고, 유효하지 않는 값이 입력될 수 있다.다음 예를 보자.```javapackage enumeration.ex0;public class StringGradeEx02 public static void main(String args) int price = 10000;DiscountService discountService = new DiscountService();// 존재하지 않는 등급int vip = discountService.discount(VIP, price);System.out.println(VIP 등급의 할인 금액: + vip);// 오타int diamondd = discountService.discount(DIAMONDD, price);System.out.println(DIAMONDD 등급의 할인 금액: + diamondd);// 소문자 입력int gold = discountService.discount(gold, price);System.out.println(gold 등급의 할인 금액: + gold);```**실행 결과**```VIP: 할인XVIP 등급의 할인 금액: 0DIAMONDD: 할인XDIAMONDD 등급의 할인 금액: 0gold: 할인Xgold 등급의 할인 금액: 0```예제에서는 다음과 같은 문제가 발생했다.존재하지 않는 VIP라는 등급을 입력했다.오타: DIAMOND 마지막에 D가 하나 추가되었다.소문자 입력: 등급은 모두 대문자인데, 소문자를 입력했다.등급에 문자열을 사용하는 지금의 방식은 다음과 같은 문제가 있다.**타입 안정성 부족**: 문자열은 오타가 발생하기 쉽고, 유효하지 않은 값이 입력될 수 있다.**데이터 일관성**: GOLD, gold, Gold 등 다양한 형식으로 문자열을 입력할 수 있어 일관성이 떨어진다.**String 사용 시 타입 안정성 부족 문제****값의 제한 부족**: `String `으로 상태나 카테고리를 표현하면, 잘못된 문자열을 실수로 입력할 가능성이 있다. 예를들어, Monday, Tuesday 등을 나타내는 데 `String `을 사용한다면, 오타(Munday)나 잘못된 값(Funday)이 입력될 위험이 있다.**컴파일 시 오류 감지 불가**: 이러한 잘못된 값은 컴파일 시에는 감지되지 않고, 런타임에서만 문제가 발견되기 때문에 디버깅이 어려워질 수 있다.이런 문제를 해결하려면 특정 범위로 값을 제한해야 한다. 예를 들어 `BASIC `, `GOLD `, `DIAMOND `라는 정확한 문자만`discount() ` 메서드에 전달되어야 한다. 하지만 `String `은 어떤 문자열이든 받을 수 있기 때문에 자바 문법 관점에서는 아무런 문제가 없다. 결국 `String ` 타입을 사용해서는 문제를 해결할 수 없다.문자열과 타입 안전성2이번에는 대안으로 문자열 상수를 사용해보자. 상수는 미리 정의한 변수명을 사용할 수 있기 때문에 문자열을 직접 사용하는 것 보다는 더 안전하다.```javapackage enumeration.ex1;public class StringGrade public static final String BASIC = BASIC;public static final String GOLD = GOLD;public static final String DIAMOND = DIAMOND;```javapackage enumeration.ex1;public class DiscountService public int discount(String grade, int price) int discountPercent = 0;if (grade.equals(StringGrade.BASIC)) discountPercent = 10; else if (grade.equals(StringGrade.GOLD)) discountPercent = 20; else if (grade.equals(StringGrade.DIAMOND)) discountPercent = 30; else System.out.println(grade + : 할인X);return price * discountPercent / 100;```javapackage enumeration.ex1;public class StringGradeEx11 public static void main(String args) int price = 10000;DiscountService discountService = new DiscountService();int basic = discountService.discount(StringGrade.BASIC, price);int gold = discountService.discount(StringGrade.GOLD, price);int diamond = discountService.discount(StringGrade.DIAMOND, price);System.out.println(BASIC 등급의 할인 금액: + basic);System.out.println(GOLD 등급의 할인 금액: + gold);System.out.println(DIAMOND 등급의 할인 금액: + diamond);```**실행 결과**```BASIC 등급의 할인 금액: 1000GOLD 등급의 할인 금액: 2000DIAMOND 등급의 할인 금액: 3000```문자열 상수를 사용한 덕분에 전체적으로 코드가 더 명확해졌다. 그리고 `discount() `에 인자를 전달할 때도`StringGrade `가 제공하는 문자열 상수를 사용하면 된다. 더 좋은 점은 만약 실수로 상수의 이름을 잘못 입력하면 컴파일 시점에 오류가 발생한다는 점이다. 따라서 오류를 쉽고 빠르게 찾을 수 있다.하지만 문자열 상수를 사용해도, 지금까지 발생한 문제들을 근본적으로 해결할 수 는 없다. 왜냐하면 `String ` 타입은어떤 문자열이든 입력할 수 있기 때문이다. 어떤 개발자가 실수로 `StringGrade `에 있는 문자열 상수를 사용하지 않고, 다음과 같이 직접 문자열을 사용해도 막을 수 있는 방법이 없다.```javapac

    2024.05.11 / 33pages ( 대학레포트 > 시험/강의/학업)

    태그 문자열 등급 , 열거 금액 , 5 열거형 - EN
  • img
  • 6 날짜와 시간
  • 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편 김영한의 실전 자바 중급 1편6. 날짜와 시간#1.인강/0.자바/3.자바-중급1편/날짜와 시간 라이브러리가 필요한 이유/자바 날짜와 시간 라이브러리 소개/기본 날짜와 시간 - LocalDateTime/타임존 - ZonedDateTime/기계 중심의 시간 - Instant /기간, 시간의 간격 - Duration, Period/날짜와 시간의 핵심 인터페이스/날짜와 시간 조회하고 조작하기1/날짜와 시간 조회하고 조작하기2/날짜와 시간 문자열 파싱과 포맷팅/문제와 풀이1/문제와 풀이2/정리날짜와 시간 라이브러리가 필요한 이유날짜와 시간을 계산하는 것은 단순하게 생각하면 쉬워보이지만, 실제로는 매우 어렵고 복잡하다.왜 그런지 이유를 하나하나 살펴보자.1. 날짜와 시간 차이 계산특정 날짜에서 다른 날짜까지의 정확한 일수를 계산하는 것은 생각보다 복잡하다. 윤년, 각 달의 일수 등을 모두 고려해야 하며, 간단한 뺄셈 연산으로는 정확한 결과를 얻기 어렵다.**예시**2024년 1월 1일에서 2024년 2월 1일까지는 몇 일일까? 이 계산은 1월이 31일 까지라는 점을 고려해야 한다. 각각의월 마다 날짜가 다르다.2. 윤년 계산지구가 태양을 한 바퀴 도는 데 걸리는 평균 시간은 대략 365.2425 일, 즉 365일 5시간 48분 45초 정도이다. 우리가사용하는 그레고리력(현재 대부분의 세계가 사용하는 달력)은 1년이 보통 365일로 설정되어 있다. 따라서 둘의 시간이정확히 맞지 않다. 이런 문제를 해결하기 위해 4년마다 하루(2월 29일)를 추가하는 윤년(**leap year**)을 도입한다. 쉽게 이야기해서 2월은 보통 2월 28일까지 있는데, 4년마다 한번은 2월이 29일까지 하루 더 있다.윤년 계산은 간단해 보이지만 실제로는 매우 복잡하다. 윤년은 보통 4년마다 한 번씩 발생하지만, 100년 단위일 때는윤년이 아니며, 400년 단위일 때는 다시 윤년이다.이 규칙에 따라, 2000년과 2020년은 윤년이지만, 1900년과 2100년은 윤년이 아니다. 이러한 규칙을 사용함으로써달력 연도는 태양 연도에 매우 가깝게 유지될 수 있다.**예시**2024년 1월 1일에서 2024년 3월 1일까지는 몇 일일까? 이 계산은 2024년이 윤년으로 2월이 29일 까지라는 점을 고려해야 한다.3. 일광 절약 시간(Daylight Saving Time, DST) 변환보통 3월에서 10월은 태양이 일찍 뜨고, 나머지는 태양이 상대적으로 늦게 뜬다. 시간도 여기에 맞추어 1시간 앞당기거나 늦추는 제도를 일광 절약 시간제 또는 썸머타임이라 한다. 일광 절약 시간은 국가나 지역에 따라 적용 여부와 시작 및종료 날짜가 다르다. 이로 인해 날짜와 시간 계산 시 1시간의 오차가 발생할 수 있으며, 이를 정확히 계산하는 것은 복잡하다.줄여서 DST는 각 나라마다 다르지만 보통 3월 중순 ~ 11월 초 정도까지 시행된다.참고로 대한민국에서는 1988년 이후로는 시행하지 않는다.**예시**특정 지역에서는 3월의 마지막 일요일에 DST가 시작되어 10월의 마지막 일요일에 종료된다. 이 기간 동안 발생하는모든 날짜와 시간 계산은 1시간을 추가하거나 빼는 로직을 포함해야 한다4. 타임존 계산세계는 다양한 타임존으로 나뉘어 있으며, 각 타임존은 UTC(협정 세계시)로부터의 시간 차이로 정의된다. 타임존 간의날짜와 시간 변환을 정확히 계산하는 것은 복잡하다.**타임존 목록**Europe/LondonGMTUTCUS/Arizona -07:00America/NewYork -05:00A sia/Seoul +09:00A sia/Dubai +04:00A sia/Istanbul +03:00A sia/Shanghai +08:00Europe/Paris +01:00Europe/Berlin +01:00**GMT, UTC**London/ UTC / GMT는 세계 시간의 기준이 되는 00:00 시간대이다.**GMT (그리니치 평균시, Greenwich Mean Time)**처음 세계 시간을 만들 때 영국 런던에 있는 그리니치 천문대를 기준으로 했다. 태양이 그리니치 천문대를 통과할 때를정오로 한다.**UTC(협정 세계시, Universal Time Coordinated)**역사적으로 GMT가 국제적인 시간 표준으로 사용되었고, UTC가 나중에 이를 대체하기 위해 도입되었다.둘 다 경도 0°에 위치한 영국의 그리니치 천문대를 기준으로 하며, 이로 인해 실질적으로 같은 시간대를 나타낸다. 그러나 두 시간 체계는 시간을 정의하고 유지하는 방법에서 차이가 있다.UTC는 원자 시계를 사용하여 측정한 국제적으로 합의된 시간 체계이다. 지구의 자전 속도가 변화하는 것을 고려하여윤초를 추가하거나 빼는 방식으로 시간을 조정함으로써, 보다 정확한 시간을 유지한다. 우리가 일반적으로 사용할 때는GMT와 UTC는 거의 차이가 없기 때문에 GMT와 UTC가 종종 같은 의미로 사용될 수 있지만, 정밀한 시간 측정과 국제적인 표준에 관해서는 UTC가 선호된다.**예시****상황:** 서울에 있는 사람이 독일 베를린에 있는 사람과 미팅을 계획하고 있다. 서울의 타임존은 A sia/Seoul, UTC+9에위치해 있고, 베를린의 타임존은 Europe/Berlin, UTC+1에 위치해 있다. 서울에서 오후 9:00에 미팅을 하려면 베를린에서는 몇 시일까?**타임존 차이**: 서울(UTC+9)와 베를린(UTC+1) 사이의 타임존 차이는 8시간이다. 이는 서울의 시간이 베를린의 시간보다 8시간 더 앞서있다는 것을 의미한다.**계산**:서울 시간: 오후 9시베를린 시간: 오후 9시 - 8시간 = 오후 1시**주의할 점****일광 절약 시간(DST)**: 일광 절약 시간이 적용되는 경우, 타임존 차이가 변할 수 있다. 예를 들어, 베를린에서DST가 적용되면 UTC+1 UTC+2가 되어, 타임존 차이는 7시간으로 줄어든다.예를 들어 베를린의 경우 3월 마지막 일요일에서 10월 마지막 일요일까지 DST가 적용된다.이러한 복잡성 때문에 대부분의 현대 개발 환경에서는 날짜와 시간을 처리하기 위해 잘 설계된 라이브러리를 사용해야한다. 이러한 라이브러리는 위에서 언급한 복잡한 계산을 추상화하여 제공하므로, 개발자는 보다 안정적이고 정확하며효율적인 코드를 작성할 수 있다.자바 날짜와 시간 라이브러리의 역사자바는 날짜와 시간 라이브러리를 지속해서 업데이트 했다.**JDK 1.0 (**java.util.Date**)****문제점****타임존 처리 부족**: 초기 `Date ` 클래스는 타임존(time zone)을 제대로 처리하지 못했다.**불편한 날짜 시간 연산**: 날짜 간 연산이나 시간의 증감 등을 처리하기 어려웠다.**불변 객체 부재**: `Date ` 객체는 변경 가능(mutable)하여, 데이터가 쉽게 변경될 수 있었고 이로 인해 버그가 발생하기 쉬웠다.**해결책**JDK 1.1에서 `java.util.Calendar ` 클래스 도입으로 타임존 지원 개선.날짜 시간 연산을 위한 추가 메소드 제공.**JDK 1.1 (**java.util.Calendar**)****문제점****사용성 저하**: `Calendar `는 사용하기 복잡하고 직관적이지 않았다.**성능 문제**: 일부 사용 사례에서 성능이 저하되는 문제가 있었다.**불변 객체 부재**: `Calendar ` 객체도 변경 가능하여, 사이드 이펙트, 스레드 안전성 문제가 있었다.**해결책**Joda-Time 오픈소스 라이브러리의 도입으로 사용성, 성능, 불변성 문제 해결.**Joda-Time****문제점****표준 라이브러리가 아님**: Joda-Time은 외부 라이브러리로, 자바 표준에 포함되지 않아 프로젝트에 별도로추가해야 했다.**해결책**자바 8에서 `java.time ` 패키지(JSR-310)를 표준 API로 도입.**JDK 8(1.8) (java.time 패키지)**`java.time ` 패키지는 이전 API의 문제점을 해결하면서, 사용성, 성능, 스레드 안전성, 타임존 처리 등에서 크게개선되었다. 변경 불가능한 불변 객체 설계로 사이드 이펙트, 스레드 안전성 보장, 보다 직관적인 API 제공으로 날짜와 시간 연산을 단순화했다.`LocalDate `, `LocalTime `, `LocalDateTime `, `ZonedDateTime `, `Instant ` 등의 클래스를 포함한다.Joda-Time의 많은 기능을 표준 자바 플랫폼으로 가져왔다.**참고**자바가 표준으로 제공했던 `Date `, `Calendar `는 사용성이 너무 떨어지고, 문제가 많은 라이브러리였다. 이런 문제를해결하기 위해 참다참다 결국 Joda-Time이라는 오픈소스 라이브러리가 등장한다. Joda-Time의 편리함과 사용성 덕분에 이 라이브러리는 크게 대중화 되었다. 자바는 기존 날짜와 시간의 설계를 반성하고, Joda-Time을 만든 개발자를대려와서 JSR-310( `java.time `)이라는 새로운 자바 표준 날짜와 시간 라이브러리를 정의한다.실용적인 Joda-Time에 많은 자바 커뮤니티의 의견을 반영해서 좀 더 안정적이고 표준적인 날짜와 시간 라이브러리인`java.time ` 패키지가 성공적으로 완성되었다.참고로 자바 표준 ORM 기술인 JPA도 비슷한 역사를 가지고 있다. 과거 자바가 표준으로 제공하는 ORM 기술이 너무불편해서, 누군가 하이버네이트라는 ORM 오픈 소스를 만들었는데, 이 기술이 자바 표준 ORM 기술보다 더 대중화되었다. 자바는 하이버네이트를 만든 개발자를 대려와서 새로운 자바 ORM 기술 표준을 만들었는데, 이것이 바로 JPA이다.`java.time `, JPA 모두 큰 성공을 거두고 자바의 메인 표준 기술로 완전히 자리 잡았다.자바 날짜와 시간 라이브러리 소개자바 날짜와 시간 라이브러리는 자바 공식 문서가 제공하는 다음 표 하나로 정리할 수 있다.원문: https://docs.oracle.com/javase/tutorial/datet

    2024.05.11 / 56pages ( 대학레포트 > 시험/강의/학업)

    태그 날짜 시간 , 타임존 자바 , 6 날짜와 시간

위로

최근 판매 자료

img