중첩 클래스와 중첩 인터페이스

중첩 클래스 (nested class)

  • 클래스 내부에 선언한 클래스
  • 중첩 클래스를 사용하면 두 클래스의 멤버들을 쉽게 접근할 수 있고 외부에는 불필요한 관계 클래스를 감춤으로서 코드의 복잡성을 줄일 수 있음

 

중첩 인터페이스 nested interface

  • 인터페이스를 클래스 내부에서 선언하는 경우
  • 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해서 사용

 

중첩 클래스

  • 멤버 클래스: 클래스의 멤버로서 선언되는 중첩 클래스
  • 로컬 클래스: 생성자 또는 메소드 내부에서 선언되는 중첩 클래스
  • 멤버 클래스는 클래스나 객체가 사용 중이라면 언제든지 재사용이 가능하지만 로컬 클래스는 메소드 실행할 때만 사용되고 메소드가 종료되면 없어짐

 

중첩 클래스 바이트 코드 파일 => A $ B . class
  • A는 바깥 클래스, B는 멤버 클래스

 

로컬 클래스 바이트 코드 파일 => A $1 B .class
  • A는 바깥 클래스, B는 로컬 클래스

 

인스턴스 멤버 클래스

  • static 키워드 없이 중첩 선언된 클래스
  • 인스턴스 멤버 클래스는 인스턴스 필드와 메소드만 선언이 가능하고 정적 필드와 메소드는 선언할 수 없음

 

class A {
	/**인스턴스 멤버 클래스**/
    class B {
    	B() {} //생성자
        int field1; //인스턴스 필드
        //static int field2; // 정적필드 (x)
        void method1() {} //인스턴스 메소드
        //static void method2() {} // 정적 메소드 (x)
        }
 }

 

정적 멤버 클래스

  • static 키워드로 선언된 클래스
  • 모든 종류의 필드와 메소드를 선언 할 수 있음
class A {
	/**정적 멤버 클래스**/
    static class C {
    	C() {} //생성자
        int field1; //인스턴스 필드
        static int field2; // 정적필
        void method1() {} //인스턴스 메소드
        static void method2() {} // 정적 메소드
        }
 }

 

 

로컬 클래스

메소드 내에서 중첩 클래스 선언

  • 로컬 클래스는 접근 제한자 및 static을 붙일 수 없음
  • 로컬 클래스는 메소드 내부에서만 사용되므로 접근을 제한할 필요가 없음
  • 로컬 클래스 내부에는 인스턴스 필드와 메소드만 선언할 수 있음
  • 정적 필드와 메소드는 선언할 수 없음
  • 로컬 클래스는 메소드가 실행될 때 메소드 내에서 객체를 생성하고 사용해야 함

 

중첩 클래스의 접근 제한

  • 멤버 클래스 내부에서 바깥 클래스의 필드와 메소드에 접근할 때는 제한이 있음
  • 메소드의 매개변수나 로컬 변수를 로컬 클래스에서 사용할 때도 제한이 있음

 

바깥 필드와 메소드에서 사용 제한

  • 바깥 클래스에서 인스턴스 멤버 클래스를 사용할 때 제한
  • 인스턴스 멤버 클래스는 바깥 클래스의 인스턴스 필드의 초기값이나 인스턴스 메소드에서 객체를 생성할 수 있음
  • 정적 필드의 초기값이나 정적 메소드에서는 객체를 생성할 수 없음
  • 정적 멤버 클래스는 모든 필드의 초기값이나 모든 메소드에서 객체를 생성할 수 있음

 

멤버 클래스에서 사용제한

  • 멤버 클래스가 인스턴스 또는 정적으로 선언됨에 따라 멤버 클래스 내부에서 바깥 클래스의 필드와 메소드에 접근할 때에도 제한이 있음
  • 인스턴스 멤버 클래스 안에서는 바깥 클래스의 모든 필드와 모든 메소드에 접근 가능
  • 정적 멤버 클래스 안에서는 바깥 클래스의 정적필드와 메소드에만 접근할 수 있고 인스턴스 필드와 메소드에는 접근할 수 없음

 

로컬클래스에서 사용 제한

  • 메소드의 매개 변수나 로컬 변수를 로컬 클래스에서 사용할 때 제한
  • 로컬 클래스의 객체는 메소드 실행이 종료되면 없어지는 것이 일반적이지만 로컬 스레드 객체를 사용하면 계속 실행상태로 존재
  • 매개 변수나 로컬 변수가 수정되어 값이 변경되면 로컬 클래스에 복사해둔 값과 달라지므로 문제를 해결하기 위해 매개변수나 로컬 변수를 final로 선언할것을 요구 -> 자바 8부터는 final 선언을 하지 않아도 값이 수정될 수 없도록 final 특성을 부여함

 

중첩 클래스에서 바깥 클래스 참조 얻기

  • 중첩 클래스에서 this 키워드를 사용하면 바깥 클래스의 객체 참조가 아니라, 중첩 클래스의 객체 참조가 됨
  • 중첩 클래스 내부에서 this.필드, this.메소드()로 호출하면 중첩 클래스의 필드와 메소드가 사용됨
  • 중첩 클래스 내부에서 바깥크 ㄹ래스의 객체 참조를 얻으려면 바깥 클래스의 이름을 this 앞에 붙여주면 됨
바깥클래스.this.필드;
바깥클래스.this.메소드();

 

중첩 인터페이스

  • 클래스 멤버로 선언된 인터페이스
  • 인터페이스를 클래스 내부에서 선언하는 이유는 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해서임
  • 중첩 인터페이스는 인스턴스 멤버 인터페이스와 정적멤버 인터페이스 모두 가능
  • 인스턴스 멤버 인터페이스는 바깥 클래스의 객체가 있어야 사용 가능
  • 정적 멤버 인터페이스는 바깥 클래스의 객체 없이 바깥 클래스만으로 바로 접근 가능
  • UI 프로그래밍에서 이벤트를 처리할 목적으로 많이 활용
class A {
	[static] interface I {
    void method();
    }
}

 

확인문제

  • 인스턴스 멤버 클래스는 바깥 클래스의 객체가 있어야 사용될 수 있다. (o)
  • 정적 멤버 클래스는 바깥 클래스의 객체가 없어도 사용될 수 있다 (o)
  • 인스턴스 멤버 클래스는 내부에는 바깥 클래스의 필드와 메소드를 사용할 수 있다. (o)
  • 정적 멤버 클래스 내부에는 바깥 클래스의 인스턴스 필드를 사용할 수 있다. (x)
  • 로컬 클래스는 생성자 또는 메소드 내부에 선언된 클래스를 말한다. (o)
  • 로컬클래스도 필드와 생성자를 가질 수 있다. (o)
  • 로컬 클래스는 static 키워드를 이용해서 정적 클래스로 만들 수 있다. (x)
  • final 특성을 가진 매개 변수나 로컬 변수만 로컬 클래스 내부에서 사용할 수 있다. (o)

글자수 양식 제한 구현 Spring boot

Jakarta Bean Validation Constraints 사용 방법

아이디나 비밀번호에 작성 제한(글자수, 한글, 특수문자 등)을 둘 때 쓰는 @Size 나 @Pattern 이 들어있는 패키지입니다.

 

아래 코드를 Build.gradle의 dependencies 에 입력하시면 사용할 수 있습니다.

 

implementation 'org.springframework.boot:spring-boot-starter-validation'

 

@Size @Pattern 사용 아이디 비밀번호 제한 두기

@Size 사용 방법

@Size 어노테이션이 붙은 element는 지정한 값의 사이(지정값 포함)에 있어야 합니다. 

 

최소값과 최대값을 결정할 수 있습니다.

 

jakarta.validation.constraints를 사용하기 위해 아래를 import 합니다.

import jakarta.validation.constraints.Size;

 

제한을 두고 싶은 변수 위에 아래 어노테이션을 입력하고,

 

@Size

최소길이값은 min = 4

최대길이값은 max = 10

 

@Size(min=4, max=10)

필요하다면 뒤에 메세지를 추가 할 수 있습니다.

 

@Pattern 사용 방법

@Pattern 어노테이션이 붙은 element는 특정한 조건을 만족해야 합니다.

 

 

jakarta.validation.constraints를 사용하기 위해 아래를 import 합니다.

import jakarta.validation.constraints.Pattern;

 

제한을 두고 싶은 변수 위에 아래 어노테이션을 입력합니다

@Pattern

정규표현식(Regular Expression)을 사용해서 조건을 입력합니다.

regexp= 조건

@Pattern(regexp = "[a-z0-9]*$")
정규 표현식(Regular Expression) 설명
^[0-9]*$ 숫자
^[a-zA-Z]*$ 영문
^[가-힣]*$ 한글
\\w+@\\w+\\.\\w+(\\.\\w+)? 이메일주소
[] 문자의 집합 범위
{} 횟수 또는 범위
* 문자가 1번이상 발생
^ 문자열의 시작
$ 문자열의 끝
\ 확장 문자의 시작
\w 알파벳이나 숫자

 

 

 

아이디, 비밀번호 입력 제한 예시

// nullable: null 허용 여부
// unique: 중복 허용 여부 (false 일때 중복 허용)
@Column(nullable = false, unique = true)
@Size(min = 4, max = 10, message = "아이디의 길이는 4자에서 10자 사이입니다")
@Pattern(regexp = "[a-z0-9]*$", message = "아이디 형식이 일치하지 않습니다")
private String username;

@Column(nullable = false)
@Size(min = 8, max = 15, message = "비밀번호의 길이는 8자에서 15자 사이입니다")
@Pattern(regexp = "[a-zA-Z0-9`~!@#$%^&*()_=+|{};:,.<>/?]*$", message = "비밀번호 형식이 일치하지 않습니다")
private String password;

 

공식 문서

아래 Jakarta Bean Validation 공식문서를 참조하시면 도움이 됩니다.

Jakarta Bean Validation에서 사용할 수 있는 어노테이션에 대한 설명이 나와있습니다.

 

Jakarta Bean Validation specification

BeanNode, PropertyNode and ContainerElementNode host getContainerClass() and getTypeArgumentIndex(). If the node represents an element that is contained in a container such as Optional, List or Map, the former returns the declared type of the container and

jakarta.ee

 

오늘 중요한 결정을 내리고 실천계획을 세웠습니다. 무례한 사람한테 타격을 받을 뻔도 했지만 역시 중요한건 꺾이지 않는 마음입니다. 

중꺾마

회사 다닐때 무례한 사람한테 대처하는 법을 알려고 '데일 카네기의 인간관계론'을 '여러번' 읽었고 온갖 유튜브 영상도 봤는데 결국은 손절이 답이었습니다. 너무 천사같고 친절하신 분들만 있길래 안이하게 생각했는데 어딜가나 또라이 보존의 법칙은 사라지지 않습니다😃🔫

 

JWT 토큰 확인 코드

// 토큰이 있는 경우에만 관심상품 추가 가능
if (token != null) {
    if (jwtUtil.validateToken(token)) {
        // 토큰에서 사용자 정보 가져오기
        claims = jwtUtil.getUserInfoFromToken(token);
    } else {
        throw new IllegalArgumentException("Token Error");
    }

    // 토큰에서 가져온 사용자 정보를 사용하여 DB 조회
    User user = userRepository.findByUsername(claims.getSubject()).orElseThrow(
            () -> new IllegalArgumentException("사용자가 존재하지 않습니다.")
    );

 

 

스프링 로그인 회원가입 구현

스프링 주특기 숙련주차 강의 후기

여전히 불친절한 강의는 핵심만 알려주고 넘어가신다는 강의 목적에 맞게 진행되었습니다. 지난 주차보다 더 불친절해져서 곤란합니다. 우선 과제를 하면서 배운 것들을 활용해보고 모르는 것들은 기술 매니저님을 괴롭힐 예정입니다.

 

업데이트 하려는 기능

  • 로그인
  • 회원가입
  • 게시글 작성
  • 게시글 조회
  • 게시글 수정
  • 게시글 삭제

지난 주에 제출한 과제(보러가기)에 추가로 회원가입, 로그인 기능을 만들고, 로그인 후 생성된 토큰을 조회하여 해당 아이디가 작성한 글만 조회, 수정, 삭제가 가능하게 하기를 구현하는 것이 이번 주차 과제입니다.

 


 

 

열심히 하려는 사람한테 사기를 저하시키는 발언은 돈주고는 안듣습니다만!!

돈 받으면 잘듣습니다.

근데 여기는 내가 돈 준 곳이라 안들었습니다.

 

 

 

 

 

타입변환과 다형성

인터페이스의 다형성

  • 프로그램 소스 코드는 변함 없지만 구현 객체를 교체함으로써 프로그램의 실행결과가 다양해짐

 

자동 타입 변환 promotion

  • 자동타입변환 : 구현 객체가 인터페이스 타입으로 변환 되는 것
  • 인터페이스 구현 클래스를 상속해서 자식 클래스를 만들었다면 자식 객체 역시 인터페이스 타입으로 자동 타입 변환 가능
  • 필드의 다형성과 매개 변수의 다형성을 구현할 수 있음

 

필드의 다형성

  • 매개 변수의 다형성: 매개 변수 타입이 인터페이스일 경우 어떠한 구현 객체도 매개값으로 사용할 수 있고, 어떤 구현 객체가 제공되느냐에 따라 메소드의 실행결과가 다양해짐

 

강제타입변환 (casting)

  • 구현 객체가 인터페이스 타입으로 자동 타입 변환하면, 인터페이스에 선언된 메소드만 사용가능 -> 제약
  • but, 경우에 따라서 구현 클래스에 선언된 필드와 메소드를 사용해야 하는 경우 발생 -> 강제타입변환(casting) 사용 -> 다시 구현 클래스 타입으로 변환 -> 구현 클래스의 필드와 메소드 사용

 

객체 타입 확인

  • 강제 타입 변환은 구현 객체가 인터페이스 타입으로 변환되어 있는 상태에서 가능
  • 어떤 구현 객체가 변환되어 있는지 모르는 상태에서 강제타입변환 할 경우 ClassCastException 에러가 발생할 수 있음
    • -> instanceof 연산자를 사용해서 인터페이스 타입으로 변환된 객체 확인

 

확인문제

  • 구현 객체는 인터페이스 타입으로 자동 변환된다 (o)
  • 부모 클래스가 인터페이스를 구현하면 자식 클래스로부터 생성된 객체는 인터페이스 타입으로 자동 변환할 수 있다. (x)
  • 인터페이스 변수에 대입된 객체를 원래 구현 클래스 타입으로 변환하는 것을 강제 타입 변환이라고 한다 (o)
  • 메소드의 매개변수 타입이 인터페이스이면 매개값으로 모든 구현 객체를 대입하면 자동 타입 변환이 된다 (o)
  • 다형성을 구현하기 위한 조건은 메소드의 재정의와 타입 변환이다 (o)
  • 클래스 상속과 인터페이스는 모두 메소드 재정의와 티압 변환 기능이 제공되므로, 어떤 방법을 사용하든 다형성 구현이 가능하다. (o)
  • 매개 변수 타입이 클래스라면 해당 클래스로 생성된 객체만 대입이 가능하다 (x)
  • 매개 변수의 타입이 인터페이스라면 모든 구현 객체가 대입이 가능하다 (o)

인터페이스 혼자공부하는자바

 

인터페이스

  • 개발 코드와 객체가 서로 통신하는 접점 역할
  • 개발 코드가 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출
  • 개발 코드를 수정하지 않고 사용하는 객체를 변경할 수 있음
  • 코드 변경 없이 실행 내용과 리턴값을 다양화 할 수 있음

 

인터페이스 선언

[public] interface 인터페이스이름 {...}
  • 인터페이스 선언은 class 키워드 대신에 interface 키워드 사용
  • 인터페이스는 상수 필드와 추상 메소드만을 구성 멤버로 가짐
  • 객체를 생성할 수 없기 때문에 생성자를 가질 수 없음

 

interface 인터페이스이름 {
	//상수
    타입 상수이름 = 값;
    //추상 메소드
    타입 메소드이름(매개변수, ...);
}

 

상수 필드(constant field) 선언

  • 인터페이스에 고정된 값으로 실행시에 데이터 변경 불가능
[public static final] 타입 상수이름 = 값;

 

 

추상메소드 선언

  • 인터페이스의 메소드는 실행 블록이 필요 없는 추상 메소드로 선언
  • 추상 메소드는 리턴 타입 메소드 이름, 매개 변수만 기술되고 중괄호 {} 를 붙이지 않는 메소드

 

인터페이스 구현

  • 인터페이스 메소드를 호출하면 인터페이스는 객체의 메소드를 호출함
  • 객체는 인터페이스에서 정의된 추상 메소드와 동일한 메소드 이름, 매개 타입, 리턴 타입을 가진 실체 메소드를 가져야함 -> 구현 객체(implement object), 구현 객체를 생성하는 클래스는 구현 클래스

 

구현 클래스

  • 클래스 선언 부에 Implements 키워드를 추가하고 인터페이스 이름을 명시
  • 인터페이스에 선언된 추상 메소드의 실체 메소드를 선언해야 함

 

public class 구현클래스이름 Implements 인터페이스이름 {

  //인터페이스에 선언된 추상 메소드의 실체 메소드 선언

}

 

  • 구현 클래스가 작성되면 new 연산자로 객체를 생성할 수 있음
  • 인터페이스로 구현 객체를 사용하려면 인터페이스 변수 선언 후 구현 객체를 대입
  • 인터페이스 변수는 참조 변수로 구현 객체가 대입될 경우 구현 객체의 번지를 저장

 

다중 인터페이스 구현 클래스

  • 다중 인터페이스를 구현하는 경우, 구현 클래스는 모든 인터페이스의 추상메소드에 대해 실체 메소드를 작성해야 함

 

인터페이스 사용

  • 클래스를 선언할 때 인터페이스는 필드, 생성자, 또는 메소드의 매개변수, 생성자 또는 메소드의 로컬 변수로 선언 될 수 있음

1. 인터페이스가 필드타입으로 사용 -> 필드에 구현 객체를 대입 가능

2. 인터페이스가 생성자의 매개 변수 타입으로 사용 -> new 연산자로 객체를 생성할 때 구현 객체를 생성자의 매개값으로 대입 가능

3. 인터페이스가 로컬 변수 타입으로 사용 -> 변수에 구현 객체를 대입할 수 있음

4. 인터페이스가 로컬 매개 변수 타입으로 사용될 경우 ->메소드 호출 시 구현 객체를 매개값으로 대입 가능

 

  • 구현 객체가 인터페이스 타입에 대입되면 인터페이스에 선언된 추상 메소드를 개발 코드에서 사용 가능

 

확인문제

  • 인터페이스는 객체 사용 방법을 정의해놓은 타입이다 (o)
  • new 연산자를 이용해서 인터페이스 객체를 만들 수 있다 (x)
  • 인터페이스는 상수 필드와 추상 메소드를 갖는다 (o)
  • 구현 클래스는 Implements 키워드로 인터페이스를 기술해야 한다 (o)
  • 클래스를 선언할 때 인터페이스 타입의 필드를 선언할 수 있다 (o)
  • 생성자의 매개 타입이 인터페이스일 경우 매개값으로 구현 객체를 대입한다 (o)
  • 인터페이스 타입의 로컬 변수는 선언할 수 없다 (x)
  • 메소드의 매개 타입이 인터페이스일 경우 매개값으로 구현 객체를 대입한다 (o)

 

 

이게 왜 되지

'이게 왜 되지'와 '이게 왜 안되지'의 향연입니다. 벌써 4주가 흘렀네요. 어느새 꽤 추운 날씨가 되었습니다. 이번주는 주특기 입문주차가 끝나고 숙련주차가 시작되었습니다. Spring이 왜 좋은지, 왜 사용하는 지에 대해서 알아가고 있습니다.

 

DI Dependency Injection 의존성 주입

객체를 직접 생성하지 않고 외부에서 생성한 후 주입시키는 방법입니다. 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴으로 인터페이스를 사이에 둬서 클래스 레벨에서는 의존 관계가 고정되지 않도록합니다. 런타임 시에는 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮출 수 있게 해줍니다.

 

두 객체 간의 관계를 맺어주는 것을 의존성 주입이라고 합니다. 생성자 주입, 필드 주입, setter 주입 등 다양한 주입 방법이 있지만 스프링에서는 생성자 주입을 권합니다. 특이 케이스가 아닌 경우 생성자 주입을 사용한다고 합니다. 

 

의존성이란 A가 변하면 그 영향이 B에 영향을 끼치는 것을 말합니다.

 

의존성 주입을 사용한다면 가독성이 높아질 뿐만 아니라 의존성이 줄어들어서 변경과 재사용이 용이해집니다.

 

관련 어노테이션에 대해서는 아래 포스팅을 참고해주시길 바랍니다.

 

TIL Spring @Component @Autowired 어노테이션 제어의 역전 221203

@Service 어노테이션 @Component 어노테이션 @Service 어노테이션은 @Component 어노테이션을 가지고 있음 -> 스프링이 자동으로 객체를 만들고 실행하는 흐름을 가져간다. 필요한 것을 알아서 생성해서 코

pizzathedeveloper.tistory.com

 

제어의 역전 IoC Inversion of Control

 

Don't call us, We'll call you

스프링을 사용할 때 개발자가 Controller, Service 등 객체를 직접 구현하기는 하지만, 해당 객체들이 언제 호출되는 지는 걱정하지않아도 됩니다. 스프링 프레임워크가 알아서 해당 객체들을 생성하고, 메서드를 호출하고 소멸시킵니다.

 

스프링을 사용하기 전에는 main 함수를 써서 직접 실행을 제어했지만 스프링 프레임워크를 사용하면서 제어권이 스프링에 넘어가게 된 것입니다. 이를 제어의 역전, Inversion of Control이라고 말합니다.

 

IoC의 장점은 아래와 같습니다.

  • 프로그램의 진행 흐름과 구현을 분리 할 수 있습니다.
  • 개발자는 비지니스 로직에 집중할 수 있습니다.
  • 객체간 의존성이 낮아집니다.
  • 코드가 유연해집니다.

 

빈 Bean

스프링 프레임워크의 IoC가 관리하는 객체를 Bean 이라고 합니다.

빈이 생성되면 말 그대로 콩 모양 아이콘이 생깁니다.

빈 아이콘

빈은 @Bean, @Component, @Service, @Repository와 같은 어노테이션으로 생성 될 수 있으며 개발자가 직접 설정할 수도 있습니다. @Component를 상속받는 어노테이션들은 모두 빈을 등록할 수 있습니다. 

 

개발자가 직접 빈 등록을 하려고 한다면 @Configuration 어노테이션을 사용합니다.

 

3주차 회고

할 일이 너무 많고 배워야하는 게 너무 많은데 다 못하고 있습니다. 새벽 늦게까지 공부를 한다고 해도 할 게 너무 많습니다. 그래도 이제는 CRUD의 원리와 기본 개념을 탑재하게 되었습니다.

 

JPA를 왜 사용하는지도 배우고,

 

 

TIL JPA 심화 영속성 컨텍스트 @Enumerated (feat. 꿈에서도 코딩)221202

어제 팀원들이랑 대화하다가 새벽 3시쯤 잠들어서 파워냅 30분했는데 코딩하는 꿈을 꿨습니다...😱 하루종일 코딩만 생각하니 이런 꿈도 꿉니다. 오늘은 주특기 2주차 시작일로 Spring 숙련주차입

pizzathedeveloper.tistory.com

 

CRUD를 구현하는 과제도 해보고,

 

TIL Spring boot 1주차 개인 과제 CRUD Postman JPA 221129

결국엔 해냈습니다!! 물론.. 수업에서 실습한 코드를 베이스로 작성한 것이지만요. 오늘 구현한 기능은 아래와 같습니다. 전체 게시글 수정 및 삭제: 제목, 작성자명, 작성 내용을 비밀번호를 일

pizzathedeveloper.tistory.com

 

자바 공부도 꾸준히 하고 있습니다.

 

 

혼자공부하는자바 7-3 추상 클래스

추상 클래스 객체를 직접 생성할 수 있는 클레스들의 공통적인 특성을 추철해서 선언한 클래스 추상클래스가 부모, 실체 클래스가 자식으로 구현되어 실체 클래스는 추상 클래스의 모든 특성을

pizzathedeveloper.tistory.com

 

 

남궁성 자바의 정석 기초편 ch 7 디폴트 메서드 static 메서드

디폴트 메서드와 static 메서드 인터페이스에 디폴트 메서드, static 메서드 추가 가능 (JDK1.8부터) 인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어려움 해결책 => 디폴트 메서드(default method

pizzathedeveloper.tistory.com

 

여러가지를 하면서 한주가 순식간에 지나갔습니다.

 

알고리즘 공부를 하나도 못해서 큰일입니다. 

다음 주에는 적어도 이틀에 한 문제는 풀려고 합니다.

 

4주차도 화이팅😎😎

스프링 개념 잡기

@Service 어노테이션 @Component 어노테이션

@Service 어노테이션은 @Component 어노테이션을 가지고 있음

-> 스프링이 자동으로 객체를 만들고 실행하는 흐름을 가져간다.

     필요한 것을 알아서 생성해서 코드의 실행을 Spring Framework가 제어하고 흐름을 제어한다 == 제어의 역전(Ioc)

 

정리

  1. 스프링이 코드의 실행 제어권을 갖는다
  2. 서버에 실행에 필요한 객체 선언 -> 스프링이 해당 객체의 인스턴스를 생성 후 사용
  3. 특정 객체가 특정 기능을 구현하는데 꼭 필요한 다른 객체가 있는 경우 -> @Component 어노테이션 사용 

 

@Autowired 어노테이션

다른 객체 생성에 또 다른 객체가 필요한 경우 해당 객체에 @Autowired를 붙인다.

  1. @Autowired를 필드에 직접 주입하면 스프링이 생성해서 넣어줌 (위험)
  2. @Autowired를 setter에 붙여서 스프링이 생성해서 넣어줌 (얘도 위험)
  3. @Autowired를 생성자에 붙여서 스프링이 생성해서 넣어줌

특이 케이스가 아닌경우 생성자 주입을 사용한다.

생성자 주입은 final 필드 값을 넣어주는 생성자를 생성하고 @Autowired를 입력하면 된다.

생성자 주입 시, @Autowired는 생략이 가능하다.

 

롬복 사용시, 필수값들이 다 들어가는 생성자를 자동으로 만들어주는 @RequiredArgsConstructor 를 쓰면 생성자 구현을 안해도 된다.

선언만 하면 알아서 만들어 준다.

 

결론

스프링이 대부분의 필수적으로 들어가는 귀찮은 작업들을 해주므로 개발자는 신경을 덜 써도 된다.

지금 다 이해하지 않더라도 왜 좋은지는 알고 가면 된다. 나중에 깊게 알아보고 지금은 기능 구현에 집중하기. 

 

 

 

쿠키와 세션

HTTP는 상태를 저장하지 않는 Stateless 특성을 가지고 있습니다. HTTP 상태는 기억되지 않기 때문에 쿠키와 세션을 이용해서 HTTP에 상태 정보를 유지(Stateful)하기 위해 사용합니다. 

 

쿠키와 세션을 통해 서버에서 클라이언트 별로 인증 및 인가가 가능합니다.

 

쿠키 Cookie

  • 클라이언트에 저장 될 목적으로 생성한 파일
  • 개발자도구 - Application - Storage - Cookies 에서 확인 가능
  • 구성 요소
    • Name: 구별하는데 사용되는 키 (중복 x)
    • Value: 쿠키의 값
    • Domain: 쿠키가 저장된 도메인
    • Path: 쿠키가 사용되는 경로
    • Expires: 쿠키의 만료기한
  • 보안에 취약함
    • 클라이언트에서 쿠키 정보를 쉽게 변경, 삭제, 및 가로채기 당할 수 있음

 

세션 Session

  • 서버에서 일정시간 동안 클라이언트 상태를 유지하기 위해 사용
  • 서버에서 클라이언트 별로 유니크 '세션 ID'를 부여한 후 클라이언트 별 필요한 정보를 서버에 저장
  • 서버에서 생성한 세션ID는 클라이언트의 쿠키값(aka. 세션 쿠키)으로 저장되어 클라이언트 식별에 사용

 

세션 동작 방식

  1. 클라이언트가 서버에 1번 요청
  2. 서버가 세션ID를 생성 -> 응답 헤더에 전달
  3. 클라이언트가 쿠키를 저장 (세션 쿠키)
  4. 클라이언트가 서버에 2번째 요청  - 쿠키값(세션ID) 포함 요청
  5. 서버가 세션ID를 확인 -> 1번 요청과 같은 클라이언트임을 확인

 

쿠키와 세션 비교하기

  쿠키(Cookie) 세션(Session)
설명 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일 서버에서 일정시간 동안 클라이언트 상태를  유지하기 위해 사용
저장 위치 클라이언트 (웹 브라우저) 웹 서버
사용 예시 팝업 "오늘 다시보지 않기" 정보 저장 로그인 정보 저장
만료 시점 쿠키 저장 시 만료일시 설정 가능
(브라우저 종료시에도 유지 가능)
다음 조건 중 하나가 만족될 경우 만료됨
1. 브라우져 종료 시
2. 클라이언트 로그아웃 시
3. 서버에 설정한 유지기간까지 해당 클라이언트의 재요청이 없는 경우
용량 제한 브라우저 별로 상이
크롬기준:
   도메인 당 180개
   쿠키 당 4KB
개수 제한 없음
보안 취약 비교적 안전
(서버에 저장 되기 때문에)

 

 

결론

쿠키와 세션을 통해 클라이언트 별로 인증 및 인가를 할 수 있습니다. 

추상 클래스

추상 클래스

  • 객체를 직접 생성할 수 있는 클레스들의 공통적인 특성을 추철해서 선언한 클래스
  • 추상클래스가 부모, 실체 클래스가 자식으로 구현되어 실체 클래스는 추상 클래스의 모든 특성을 물려받고 추가적인 특성(필드, 메소드)을 가질 수 있음

 

추상 클래스의 용도

  • 공통된 필드와 메소드의 이름을 통일할 목적
  • 실체 클래스를 작성할 때 시간 절약
  • 작성해야할 클래스가 다수이고 이 클래스들이 동일한 필드와 메소드를 가져야 할 경우, 설계자는 공통된 부분을 춯상 클래스로 설계하는 것이 좋음
  • 추상 클래스를 상속해서 구체적인 클래스를 만듦

 

추상 클래스 선언

public abstract class 클래스 {
	//필드
    //생성자
    //메소드
}
  • abstract를 붙이면 new 연산자를 이용해서 객체 못만들고 상속을 통해 자식 클래스만 만들 수 있음
  • new 연산자로 직접 호출할 수는 없지만 자식 객체가 생성될 때 super(...)를 호출해서 추상 클래스 객체를 생성
  • 추상 클래스도 생성자가 반드시 있어야 함

 

public abstract class Phone {
	//필드
    public String owner;
    
    //생성자
    public Phone(String owner) v{
    	this.owner =owner;
    }
    
    //메소드
    public void turnOn() {
      System.out.println("폰 전원을 켭니다.");
    }
    public void turnOff() {
      System.out.println("폰 전원을 끕니다.");
    } 
  }

 

  • 부모 클래스의 super(owner) 코드로 생성자를 호출함

 

public abstract class SmartPhone extends Phone {
    
    //생성자
    public SmartPhone(String owner) v{
    	super(owner);
    }
    
    //메소드
    public void internetSearch() {
      System.out.println("인터넷 검색을 합니다.");
    }
    
    } 
  }

 

추상 메소드와 재정의

  • 추상클레스는 실체 클래스의 멤버(필드, 메소드)를 통일하는 게 목적
  • 모든 실체들이 가지고 있는 메소드의 실행 내용일 동일하면 추상 클래스에 메소드를 작성
  • 메소드 선언만 통일하고 실행 내용은 실체 클래스마다 달라야 하는 경우 -> 추상 클래스는 추상 메소드 선언 가능

 

[public | protected] abstract 리턴타입 메소드이름(매개변수, ...);
  • 추상 클래스 설계 시 하위 클래스가 실행 내용을 반드시 채우도록 강제하고 싶은 메소드가 있을 경우 추상 메소드 선언
  • 자식 클래스는 반드시 추상 메소드를 재정의해서 실행 내용 작성해야함 -> 아니면 컴파일 에러 발생

 

확인문제

  • 추상 클래스는 직접 new 연산자로 객체를 생성할 수 없다 (o)
  • 추상 클래스는 부모 클래스로만 사용 (o)
  • 추상 클래스는 실체 클래스들의 공통된 특성(필드, 메소드)로 구성된 클래스이다. (o)
  • 추상 클래스에는 최소한 하나의 추상 메소드가 있어야 한다 (x)
  • 추상 메소드는 선언부만 있고 실행 블록을 가지지 않는다 (o)
  • 추상 메소드는 자식 클래스에서 재정의 해서 실행 내용을 결정해야 한다 (o)
  • 추상 메소드를 재정의 하지 않으면 자식 클래스도 추상 클래스가 되어야 한다 (o)
  • 추상 메소드가 있더라도 해당 클래스가 꼭 추상 클래스가 될 필요는 없다 (x)

+ Recent posts