본문 바로가기
Today I Learned 2024. 4. 23.

(24.04.23)[2주차] Java문법 종합반 강의(컬렉션, 클래스, 상속, 인터페이스 + 실습 문제 풀이)

어제에 이어서 모든 내용은 진짜 Java의 기본이므로 최대한 빠르게 간단하게 정리한다의 목적으로 "Java 예습 내용 전체 정리하기" 목표를 오늘 두었다.

 

하지만, 내일은 예습 범위에 벗어난 스레드와 Optional이 있기 때문에 이부분은 학습을 확실히 하고 넘어갈 계획

그리고 추가적으로 진짜 기초를 다루는 강의이기 때문에

해당 스레드, 입출력 부분은 Java의 정석을 통해 다시 심화 공부를 스스로 다음주 내 진행 계획

 

중간 숙제 = 점검 문제의 에러 이슈도 동일하게 하면서 알고있는 예습 내용들을 정리했다.

 

 


Java문법 종합반 강의 간단정리 및 숙제 풀기

컬렉션

더보기

컬렉션 Collections

  • 참조형 데이터를 효과적으로 다루기 위한 프레임워크

List

  • 데이터 순서간 있는 구조

ArrayList

  • Array와 달리 가변적적으로 자료를 생성할 때 마다 동적으로 자료를 추가하는 리스트

LinkedList

  • 요소의 실제 값을 두고 각 요소의 주소를 저장한 리스트
    • 조회는 Slow, 추가/삭제 Fast
  • ArrayList와 같이 사용가능

Stack

  • LIFO 형태
  • 데이터 중복 처리, 최근 데이터 사용에 용이

Queue

  • FIFO 형태
  • 공간이 비기 때문에 LinkedList 로 생성

Set

  • 중복과 순서가 없는 Unique한 데이터 집합
  • Set은 생성자가 존재하지 않기 때문에 HashSet TreeSet으로 생성, 사용

Map

  • Key-Value 의 Pair로 이뤄진 데이터 집합

숙제 풀이

Java코드

더보기
import java.sql.Array;
import java.util.EmptyStackException;
import java.util.Stack;
import java.util.*;

public class W01 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String type = sc.nextLine();
        String title = sc.nextLine();
        //List 일경우
        if (type.equals("List")) {
            ArrayList<String> List = new ArrayList<>();
            //입력된 것의 끝날 때 까지이기 때문에 for 아 아닌 while
            int i = 1;
            while (true) { //끝 입력되면 탈출시키게 하기 위해서
                String str = sc.nextLine();
                if (str.equals("끝")) {
                    List.add(str);
                    break;
                } else {
                    List.add(i + ". " + str);
                    i++;
                }
            }
            System.out.println("[ " + type + " 으로 저장된 " + title + " ]");
            for (String index : List) {
                System.out.println(index);
            }
        }

        //Set 일경우
        if (type.equals("Set")) {
            Set<String> st = new HashSet();
            //입력된 것의 끝날 때 까지이기 때문에 for 아 아닌 while
            int i = 1;
            while (true) { //끝 입력되면 탈출시키게 하기 위해서
                String str = sc.nextLine();
                if (str.equals("끝")) {
                    st.add(str);
                    break;
                } else {
                    st.add(i + ". " + str);
                    i++;
                }
            }
            System.out.println("[ " + type + " 으로 저장된 " + title + " ]");
            for (String index : st) {
                System.out.println(index);
            }
        }

        //Map 일경우
        if (type.equals("Map")) {
            Map<Integer, String> mp = new HashMap<>();
            //입력된 것의 끝날 때 까지이기 때문에 for 아 아닌 while
            int i = 1;
            while (true) { //끝 입력되면 탈출시키게 하기 위해서
                String key = sc.nextLine();
                if (key.equals("끝")) {
                    break;
                } else {
                    mp.put(i, key);
                    i++;
                }
            }
            System.out.println("[ " + type + " 으로 저장된 " + title + " ]");
            for (int j = 1; j <= mp.size(); j++) {
                System.out.println(j+". "+mp.get(j));
            }
            System.out.println("끝");
        }
    }
}
  • 가이드라인은 switch 조건문이 쓰여있지만, 실습은 일부러 다르게 if문을 활용해 보기 위해 일부러 코드가 지저분해도 if문을 사용

이슈1.  "끝"을 입력했을 때, 출력이 중간만 되는 현상

  •  while (!sc.nextLine().equals("끝")) {...} 을 작성
    • 계속 짝수번 째 입력값만 나오게됨
  • 해결 : .nextLine() 또는 Scanner나 다른 Stream으로 불러오는 메서드는 조건문일지라도 작성이되면 무조건 다음으로 넘어가는 규칙을 인지 -> .nextLine() 메서드로 가져온 요소를 다른 변수로 지정 + while 문 안에 또다른 if문을 만들어서 "끝" 이 입력되면 break 될 수 있게 로직을 변경

이슈2. Map에서 레시피의 마지막 입력값이 출력 안되는 현상

  • for (int j = 1; j < mp.size(); j++) {...} 로 반복문 작성
  • 해결 : for (int j = 1; j <= mp.size(); j++) 단순하게 = 표시를 쓰지 않았던 것, 배열의 length와 똑같이 size메서드도 똑같이 인식을 하고 있어서, 적응을 해서 실수 하지 않도록.

클래스, 상속, 인터페이스

더보기

객체

  • Object 필드와 메서드를 통해 속성과 기능을 구현하는 것 : 객체 모델링

객체의 작동

  • 메서드() 안의 매개변수 또는 매개값(파라미터)를 통해 리턴을 통해 반환이 가능

객체끼리의 상호작용이 가능

  • 사용관계
    • 상호 사용의 관계
  • 포함관계
    • 객체 끼리의 포함관계
  • 상속관계
    • 조상 객체의 시스템을 객체를 상속받는 자손 객의 상속관계 형성 가능

객체 지향 프로그래밍

캡슐화

  • 속성(필드)와 행위(메서드)를 묶어서 외부에서 접근을 제한

상속

  • 객체간의 구조를 파악에 필요
  • 일관성 유지
  • 코드 중복을 방지

다형성

  • 객체는 다르지만 조상 클래스 타입의 참조변수로 자손 클래스의 인스턴스를 참조 하여 다른 형태를 지니는 것

추상화

  • 여러 객체의 공통 부분을 묶어서 새롭게 추상적으로 묶어서 선언한 것

객체와 클래스

  • 클래스로 인스턴스화를 통해 인스턴스들을 생성

클래스 설계 & 객체 설계

클래스 선언

클래스의 필드 정의

  • 필드로 객체의 속성을 선언
    • 초기화 하지 않고 선언
  • 초기 값을 정의를 해도 가능
    • 그렇기 떄문에 초기화 없이는 null등의 초기값으로 설정

필드 접근

  • 외부 접근
  • new 이름() 로 호출
  • 내부접근
    • 그냥 이름만 쓰면 가능

클래스의 생성자 정의

  • 객체 생성 방식을 정의
  • 클래스가 생성이 될때 어떤 매개변수를 넣을 것인지 정하는 것
    • 단, 아무것도 없이 클래스 이름만 가져오는 것은 기본생성자

클래스의 메서드 정의

  • 객체가 지니는 기능, 행위를 정의
  • 만들어진 필드를 제어

메서드 선언

  • void외 리턴타입이 주어진다면 return이 항상 존재해야
  • 메서드이름()의 () 사이에 들어올 매개변수들을 순서에 맞춰서 지정

메서드 호출

  • 선언과 똑같이 사용
  • 선언을 할때와 마찬가지로 .메서드이름(매개변수) 로 인스턴스화 할 수 있어야

오버로딩

  • 같은 이름을 가진 메서드가 변수에 따라 다른 변수에 따라 기능을 다르게 가지겐 하는 것
  • 매개변수의 갯수, 타입, 순서 로 구분

인스턴스 멤버 & 클래스 멤버

인스턴스 멤버

  • 인스턴스 필드 + 인스턴스 메서드
  • 인스턴스를 통해서 메서드를 사용할 수 있도록 무조걱 객체 생성을 통해서만 가능

클래스 멤버

  • 클래스 필드 + 클래스 메서드
  • 별도로 각각 고유값을 가질 때, 생성 없이 바로 사용 가능
    • 따라서 계속 생성을 해야하는 인스턴스 멤버를 안에 쓸 수X
  • 앞에 static을 붙이면 가능

지역변수

  • 메서드 내에서만 사용할 수 있는 독립적인 변수

final 필드 & 상수

  • 초기값이 절대 바뀌지 않는 값
  • static과 함께 사용되어 static final String COMPANY = .. 로 많이 쓰임
    • 관례상 모든 상수는 대문자로 이름을 사용

생성자

  • 객체 초기화 역할
  • 단, 타입의 순서를 주의해서 오버로딩을 할 수 있어야

this & this()

this

  • Java는 참조변수일 경우 가장 가까운 참조변수라고 알기 때문에, 오류방지를 위해 자기자신에게 대입을 해야하는 경우엔 this를 사용할 수 있도록

this()

  • 이름 그대론 생성자를 가르키는 것
  • 무조건 맨 처음에 가져올 수 있어야
  • 생성자 오버로딩을 할 때마다 중복되는 코드를 가지는 다른 생성자를 this()를 사용해서 불러서 사용 가능

접근제어자

  • 클래스 변수 메서드 선언부에 모두 사용
  • public
    • 전체
  • protected
    • 같은 클래스 + 같은 패키지 + 자손 클래스
  • (default)
    • 같은 클래스 + 같은 패키지
  • private
    • 같은 클래스
    • 캡슐화 가능

캡슐화

  • 내부 선언 데이터를 보호화 가능

Getter & Setter

  • 일종의 암묵적인 메서드 이름의 규율

Package & Import

package

  • 클래스의 묶음
  • 클래스를 식별해 주는 용도
    • . 로 상위 패키지와 하위 패킫지를 구분
  • 딱 한번만 선언하여 현재의 패키지를 설정
    • 단, 다른 패키지를 적어서 클래스를 가지고 올 수 있음

import

  • package와 반대로 다른 패키지의 특정 클래스를 가지고 와서 소스파일에선 자유롭게 사용할 수 있는것

 

클래스간 관계 & 상속

상속

  • extends (부모클래스) 를 통해 멤버를 상속
  • Object는 모든 클래스의 조상 클래스

단일 상속 & 다중 상속

  • 상속은 다중상속을 허용X
    • 이름이 같은 멤버가 충돌이 일어날 수 있기 때문
  • final 클래스는 당연히 상속, 오버라이딩 모두 불가능

오버라이딩

  • 조상 클래스, 부모 클래스에서 상속받은 메서드를 다시 오버라이드 해서 새롭게 정의
    • 단, 해당 오버라이딩 할부모 클래스 메서드와 일치
    • 접근 제어자 역시 더 넓게 지정 불
    • 더 많은 예외 exception 선언 불가]

super

  • this와 유사
  • 조상 클래스, 부모 클래스에서 멤버를 참조
  • 따라서, 자손 클래스의 이름과 충돌을 방지

super()

  • super과 유사
  • 부모 클래스의 생성자를 가지고 오는 것
  • 자손 클래스가 조상 클래스의 멤버를 가지고 쓸 수 있기 때문에

다형성

  • 다운캐스팅 / 업캐스팅을 통해서 조상 / 자손 클래스를 서로 자유롭게 생성, 사용할 수 있는것
    • 단, 다운캐스팅일경우 따로 형변환을 진행해줘서 써야

참조변수의 자동변환

  • 상속관계에 있는 객체끼리 모든 조상과 자손 서로 형변환 가능
  • 즉, 자손 객체가 부모 객체를 상속받아 똑같기 때문에 이 때 부모 객체와 동일하게 취급

참조변수의 강제 변환

  • 다운 캐스팅일 경우에는 변환을 직접 해줘야
  • 단, 이미 업캐스팅이 진행이 된 경우에만 가능, 이것도 Java는 주의를 줌
    • 그 외는 다 에러

instanceof

  • 자손 클래스가 특정 조상 클래스에 종속되어있는지 boolean타입으로 반환하는 메서드

추상 클래스

  • 몸통이 없는 클래스
    • static 클래스와 정 반대
  • 상속을 해야 완성이 되는 클래스
    • 여러개의 클래스의 공통적인 적인 것을 묶어 추상화 하는 작업의 일종이라고 생각

추상 메서드

  • 매개변수는 있으나 {} 기능이 없는 메서드
  • 오버라이딩 필수

인터페이스

  • 두 객체를 연결하는 역할

선언

public interface 인터페이스이름 {…};

구성

  • 추상메서드public static final 상수를 멤버로 가지는 것
    • 컴파일러가 알아서 추가
    • 일종의 추상 클래스

구현

  • implements 를 통해서 클래스에 구현

상속

  • extends 를 통해 다른 인터페이스에 상속
  • 다중상속이 가능

인터페이스 다형성

  • 구현이 되는 클래스에서 인터페이스는 조상 클래스 이기 때문에 업스케일링 자동 형변환이 가능
    • 즉, 인터페이스A가 클래스B에 구현이 되어있다면 A a1 = new B(); 처럼 main에서 쓸 수 있다는 것
  • 업스케일링 된 것들을 다시 다운스케일링 하는 것 역시 **()** 를 활용해서 강제 다운스케일링 형변환이 가능

default 메서드

  • 인터페이스 내에서 default void 메서드이름(){} 으로 구현해서 추상메서드 업이 구현된 클래스들에 동일하게 재정의 없이 쓸 수 있게 하는 메서드

static 메서드

  • default 메서드 처럼 인터페이스 내에서 static void 메서드이름(){} 로 구현이 된 메서드
  • 컴파일러가 앞에 public을 저절로 붙여서 구현된 클래스에 쓸 수 있도록
  • static 기능을 그대로 가져오면서 쓸 수 있게 하는 메서드

 


Java 정리를 하는데 진짜 몰아치듯이 강의를 듣고 예습한 내용을 정리하니 하루가 진짜 빠르게 지나간 것 같지만

기본중에 기본이라 하나하나 다시 "점검" 하는 중이라 조금만 버티자..