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

중첩 클래스 (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)

어제 팀원들이랑 대화하다가 새벽 3시쯤 잠들어서 파워냅 30분했는데 코딩하는 꿈을 꿨습니다...😱  하루종일 코딩만 생각하니 이런 꿈도 꿉니다. 오늘은 주특기 2주차 시작일로 Spring 숙련주차입니다. 강의가 새로 지급되었고 개인과제와 팀과제가 새로 나왔습니다. 다들 월드컵 보러 갈 때 치킨으로 만족하고 강의 듣습니다.🍗🍗🍗

 

zep

JPA 심화

  • JPA는 자동으로 Id값을 찾아주지만 (@GeneratedValue 사용) Query는 Select를 사용해 최대값을 넣어서 찾아서 마지막 id값+1해서 넣어줘야 한다
  • JPA를 사용하면 query보다 간단함 
  • Spring Data JPA 사용

 

영속성 컨텍스트 Persistence context

  • 엔티티를 영구 저장 하는 환경
  • 어플리케이션이 데이터베이스에서 꺼내온 데이터 객체를 보관하는 역할
  • 영속성 컨텍스트는 엔티티 매니저를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관하고 관리함

 

1. find(”memberB”)와 같은 로직이 있을 때 먼저 1차 캐시를 조회

2. 있으면 해당 데이터를 반환

3. 없으면 그 때 실제 DB로 “SELECT * FROM….” 의 쿼리를 보냄

4. 반환하기 전에 1차캐시에 저장하고 반환

 

 

=> MemberA, MemberB를 생성할 때 마다 DB를 다녀오는건 비효율적

 

해결책 =>“쓰기 지연 SQL 저장소” Transactional write-behind

 

1. memberA, memberB를 영속화

2. entityManager.commit() 메서드를 호출

3. 내부적으로 쓰기 지연 SQL 저장소에서 Flush가 발생 -> 임의로 시점 지정 가능

4. “INSERT A”, “INSERT B”와 같은 쓰기 전용 쿼리들이 DB로 전달

 

 

@Enumerated

  • 속성으로는 Ordinal, String이 있음
  • String인경우 해당 문자열 그대로 저장해서 비용은 많이 들지만, 나중에 Enum이 변경되어도 위험할일이 없기 때문에 일반적으로는 String을 사용합니다.
  • Enum은 데이터 순서대로 값을 매기기 때문에 변경되거나 삭제시 오류가 발생할 수 있음
    • 값이 변경되어도 위험할 일이 없기 때문에 대부분 String을 사용

 

 

 

아래와 같이 오류가 뜬다면 사용중인 포트를 터미널로 찾아서 kill 할 수 잇습니다.

Web server failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.


Process finished with exit code 1

web server failed to start. Port 8080 was already in use

사용중인 포트 찾아서 kill 하는 법

1. 터미널에 들어가서 kill을 원하는 포트를 다음 코드를 입력해서 찾습니다.

ex) port 8080

lsof -i: 8080

숫자부분에 원하는 포트 번호를 입력하시면 됩니다.

 

아래와 같이 포트 정보가 출력됩니다.

 

2. 사용중인 포트 kill 하기

kill -9

또는 

kill PID숫자 를 입력하여 사용중인 포트를 kill 합니다.

위의 예시의 PID 숫자 55149를 아래와 같이 입력하였습니다

kill 55149

 

다시 코드를 실행하면 port가 잘 돌아가는 것을 확인할 수 있습니다.

 

 

벌써 12월이 되었습니다. 한달이 훌쩍 지나갔네요. 정식으로 부트캠프는 99일이라고 홍보가 되어있지만 사전 스터디 기간까지 합친다면 거진 2달의 기간이 지나갔습니다. 11월에는 자바가 무엇인지 객체지향 프로그램이 무엇인지 처음 배우는 시간이었습니다. 그동한 배우고 구현 해본 것들을 나열하자만 아래와 같습니다.

 

  • JWT를 이용해서 Flask python 회원가입, 로그인 기능 구현
  • 자바의 정석 유튜브 동영상 강의 ch 1 ~ 7
  • 프로그래머스 문제 풀이 30개
  • 혼자공부하는 자바 ch 1 ~ 7
  • 깃과 깃허브 사용해서 협업
  • 1주차 미니프로젝트 완성
  • 2주차 알고리즘 test
  • 3주차 Spring 주특기 1주차 강의
  • 객체지향 프로그래밍 과제
  • 게시판 구현 (CRUD 기능 구현: 등록, 조회, 수정, 삭제)
  • Postman 사용
  • JPA 기초
  • HTTP method (PUT, POST, DELETE 등)
  • API 명세서 작성
  • API 만들기

생각보다 한 게 많지만 없습니다.

개발자가 되기 위한 단계로 보면 이제 튜토리얼의 튜토리얼을 뗀 수준입니다. 

프로그래머의 삶

자바도 그렇고 이제 갓 배우기 시작해서 뭐든 다 새롭고 매일 엄청난 양의 새로운 정보를 습득하다 보니 혼란할 때도 많습니다. 어제 튜터님께 자바 공부를 하고 있다고 말씀드리니까 자바 백엔드 개발자 공부 로드맵을 이야기 해주셨습니다. 

 

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

 

자바 백엔드 공부 로드맵

자바 공부 로드맵

1. 자바의 정석

- 남궁성 자바의 정석 유튜브 보면서 다 따라치면서 연습하기

- 객체지향 부분은 스스로 예제 만들면서 익히기

 

2. 모던 자바인 액션

- 자바 8, 9, 10 버전을 예시와 함께 설명하는 책

 

3. 컴파일러 만들기

- 컴파일러 만들어보기

책입니다 --> 책정보 링크 클릭

 

4. 클린 코드, 이펙티브 자바

클린코드 책 구매 링크

이펙티브 자바 책 구매 링크

 

고급 개발자가 되기 위해서 읽자.

 

Gof의 디자인 패턴

(클린 코드 다음에 읽을 책)

 

schema 설계

DB 설계 중요

 

컴퓨터 공학 Network

1. MIT 유튜브 강의

2. 네트워크 공부하기

 

Spring 공부

1. 토비의 스프링 3.1 

- 좀 두꺼운 편이니까 아래 책을 먼저 읽는 것도 추천

 

2. 자바 웹프로그래밍 Next step

- 토비의 스프링보다 얇은 편

 

3. 김영한 강의도 추천

 

알고리즘 코딩 테스트 공부

하루에 1문제 풀기.

lv 순으로 풀기 보다는 bfs, dfs (최단시간) 문제 등 유형별로 풀어보기

 


12월의 목표는....

  • 자바에 대해 어느정도 익숙해지는 것
    • 자바의 정석 남궁성 유튜브 강의 완강
    • 혼자공부하는자바 완독
  • 아무것도 안보고 CRUD 혼자 구현해 보는 것
    • 이건 이번 주말에 할 겁니다
  • Spring 김영한 입문 강의 완강
    • 28개 강의
  • 알고리즘 공부
    • 2일에 한 문제씩 풀기

입니다.

 

2월 17일이 항해99 부트캠프가 끝나니까요. 그때는 얼마나 성장해 있을지 기대가 됩니다.

 

나는 2023년 1분기 이내 취직한다.

 

 

 

 

팀과제가 다 처음 배우는 것이라 Today I learned 입니다.

Spring TIL

JPA란

‘Java Persistence API’로 자바 ORM(Object Relational Mapping: 객체 관계 매핑)기술로 다음과 같은 기능을 함:

  • 쿼리 자동 생성
  • 어플리케이션 계층에서 spl 의존성을 낮춰 작업 효율성 상승
  • 패러다임 불일치 해결
  • 다양한 방언(h2 Database, mySQL, oracle 등) 지원

JPA 사용을 위해서는 Hibernate, EclipseLink 같은 ORM 프레임워크를 사용해아함.

스프링 부트에서는 Hibernate 사용

ORM(객체 관계 매핑)이란?

객체와 DB의 테이블이 매핑을 이루는 것으로 query를 직접 작성하지 않고 메서드 호출로 데이터 조회가 가능함 → 생산성 향상

스프링에서 JPA를 사용할 때 에상 가능하고 반복적인 코드들을 Spring Data JPA가 작성해줌 →JpaRepository 선언

책추천 (추천글/지은이의말 만 읽어도 도움됩니다)

 

restAPI의 put 과 patch 는 어떤 차이점이 있을까요? 어떤 경우에 사용하면 좋을까요?

Http Method 중 자원(엔티티)을 수정하는 용도 1)PUT

  • 전체 수정(자원 전체 교체) => 자원이 있다면 수정, 없다면 생성
  • 수정 시 모든 필드 필요
  • 자원 전체를 교체하는 것이기에, Client는 해당 자원 상태를 모두 알고 있다고 가정되어야 함 즉, Payload만으로 자원 전체 상태를 표시할 수 있어야 함
  • 멱등성 가짐

2)PATCH

  • 부분 수정(자원 부분 교체)
  • 수정 시 수정할 필드만 필요
  • 별도의 DTO 필요
  • 멱등성 가질 수 도, 안 가질 수도 있음

 멱등성(idemoitent)

  • 연산을 여러번 적용해도, 결과가 달라지지 않는 성질
  • 연산을 여러번 반복해도, 한번만 수행된것과 같은 성질
    • 동일한 요청을 한번 보내는 것과 여러번 연속 보내는 것이 같은 효과를 가지고, 서버 상태도 동일할 때, HTTP Method가 멱등성을 가졌다고 말함
  • ex) f(f(x)) = f(x)

HTTP란?

HyperText Transfer Protocol로 프로토콜, 즉 인터넷 통신 데이터 교환의 기준이 되는 약속이다. Stateless(무상태성)와 Connectionless(비연결성)이 특징으로 요청(request)을 주고 받을 때만 연결이 유지되고 응답(response)하고 나서 서버와 연결을 끊는다.

HTTP 메소드

클라이언트가 웹 서버에 사용자 요청의 목적 또는 종류를 알리는 수단으로 GET, POST, PUT, PATCH, DELETE 가 주로 쓰임

구성요소

  • Method (호출/요청 방식)
    • GET: 이름 그대로 어떤 리소스를 얻을 때 사용; 브라우저의 주소창에 URL을 입력하면 GET 메서드를 사용해서 서버에 요청을 보냄
    • POST: 웹 서버에 데이터를 게시할 때 사용 (ex. 회원가입, 게시글 작성, 댓글 작성)
  • Header (추가 데이터. 메타 데이터)
    • 브라우저가 어떤 페이지를 원하는지
    • 요청 받은 페이지를 찾았는지
    • 요청 받은 데이터를 성공적으로 찾았는지
    • 어떤 형식으로 데이터를 보낼지
    다양한 의사 표현을 위한 데이터를 모두 Header 필드에 넣고 주고 받음
  • 위에서 설명 된 메서드도 헤더에 포함되어 서버로 보냄
  • Payload (데이터. 실제 데이터)
    • 서버가 응답을 보낼 때에는 항상 Payload 보내기 가능
    • 클라이언트(브라우저)가 요청을 할 때에도 Payload를 보낼 수 있음
    • "GET method를 제외하곤 모두 Payload를 보낼 수 있다" 는게 HTTP에서의 약속

참고자료

 

HTTP | MDN

하이퍼텍스트 전송 프로토콜(HTTP)_은 HTML과 같은 하이퍼미디어 문서를 전송하기위한 _애플리케이션 레이어 프로토콜입니다. 웹 브라우저와 웹 서버간의 커뮤니케이션을위해 디자인되었지만, 다

developer.mozilla.org

 

(DB에서)트랜잭션(Transaction)

  • 나눌 수 없는 업무 단위
  • SQL DML에는 select(조회). insert(생성), update(수정), delete(삭제)가 있다.
  • 이 중 insert, update, delete는 Table 안에 data를 변경시킬 수 있는데(생성, 수정, 삭제) insert, update, delete SQL문을 모두 작성한 후 최종 반영(commit)할지, 취소(rollback)할지 결정해야 한다.
  • 문서파일에 글을 저장하지 않고 작성하다가 마지막에 닫기(X) 버튼 클릭하면(윈도우 기준) [저장] 또는 [저장안함]이 뜨는데, [저장]하면 사용자가 작성한 내용들이 저장되고, [저장안함]을 선택하면 사용자가 작성한 자료가 반영되지 않는다.
    • 여기서 [저장]은 commit, [저장안함]은 rollback이다.
  • SQL에서 Transaction이 필요한 이유는, DML 중 insert, update, delete가 사용자들에게 영향을 줄 수 있기 때문이다
  • Transaction은 이러한 문제를 해결하기 위해 누군가 특정 data에 작업(insert, update, delete)하려고 한다면, 작업하고 있는 data를 잠금(lock)한다.
  • 이 작업이 끝날 때까지 다른 사용자들은 해당 data를 insert, update, delete하지 못하고, 작업중인 사용자가 최종 반영할지(commit), 취소할지(rollback) 결정되면, 그때 감금이 해제된다.

 

트랜잭션 특징

원자성(Atomicity) :

  • 트랜잭션 안의 작업들이 분리되어 작업 불가
  • 트랜잭션의 가장 큰 특성 (이게 안되면 무결성이 훼손)

독립성(Isolation) :

  • 진행 중인 트랜잭션들은 정보전달, 서로 알아보기 등등 없다.
  • 트랜잭션은 하나씩만 열 수 있다. 여러 개를 같이 못함(독립성) (외부와 정보교환 수행 불가, Lock)

일관성(Consistency) :

  • 트랜잭션 실행 후 DB의 무결성은 반드시 유지 되어야 함

영속성(Durability) :

  • 작업 종료된 트랜잭션의 결과는 반드시 DB에 반영되어야 함

 

 

 

  • 스프링에서 의존성 주입이란 무엇인가?
  • 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴이다. 인터페이스를 사이에 두고 클래스 레벨에서 의존관계가 고정되지 않도록 한 후에 런타입 시에 관계를 동적으로 주입하여 유연성을 높이고 결합도를 낮출 수 있게 하는 것을 의미한다.
  • 예시-문제점) 아래의 코드는 두가지의 문제를 가지고 있다.
       **문제점 1. 두 클래스의 결합도가 높음** 
    
    → 만약 다른 타이어를 사용하고자 할 때 Car() 클래스의 직접 수정이 필요하다.→ 구현클래스를 직접 수정해야한다.
  • 문제점 2. 객체들 사이의 관계가 아닌 클래스같의 관계가 맺어져 있다.
  • public class Car() { private Tire kumhoTire; public Car() { this.kumhoTire = new kumhoTire(); } }
  • 예시-DI수행) 그럼 스프링에서의 DI를 수행해보자.
  1. 먼저 Tire 인터페이스를 생성하고 그것을 구현하는 kumhoTire 구현 클래스를 만든다.
  2. public interface Tire { } public class kumhoTire implements Tire { }
  3. 그리고 Car의 생성자를 만들고 인자값으로 Tire 객체를 받도록 만든다. 이렇게 함으로써 Car에서 kumhoTire 구체 클래스의 의존성을 제거한다.
  4. public class Car { private Tire tire; private Car(Tire tire) { this.tire = tire; } }
  5. 스프링은 애플리케이션 실행 시점에서 필요한 객체(bean)을 DI 컨테이너에서 생성한다. 그리고 의존성이 있는 두 객체를 연결하기 위해 아래와 같이 한 객체를 다른 객체로 주입시킨다.
  6. public class BeanFactory { // Bean의 생성 Tire kumhoTire = new KumhoTire(); // 의존성 주입 Car car = new Car(kumhoTire); }
  • 이러한 개념은 동시에 **제어의 역전(Inversion of Control, IOC)**라고 불린다. 왜냐하면, 어떠한 객체를 사용할지에 대한 책임을 프레임워크에 넘겼기 때문이다. 동시에 자신은 수동적으로 주입받는 객체를 사용하기 때문이다.

스프링에서 IOC (Inversion Of Control)란?

IOC는 제어의 역전, 즉 제어의 흐름을 바꾸는 것이다.

Java 프로그램에서는 각 객체들이 프로그램의 흐름을 결정하고 객체를 직접 생성하여 메소드 호출하는 방식의 작업을 했다.

사용자가 모든 작업을 제어하는 구조이다. ( A객체에서 B 객체에 있는 메소드를 사용하고 싶을 때 B 객체를 직접 A 객체 내에서 생성하고 메소드를 호출)

IOC가 적용된 경우에는 객체의 생성을 특별한 관리 위임 주체에게 맡긴다.

즉, 사용자가 객체를 직접 생성하지 않고 객체의 생성 및 소멸과 같은 생명주기에 관한 제어권을 다른 주체에게 넘긴다.

  • 클래스 내부의 객체 생성 -> 의존성 객체의 메소드 호출이 아니라, 스프링에게 제어를 위임하여 스프링이 만든 객체를 주입 -> 의존성 객체의 메소드 호출 구조이다.
  • 모든 의존성 객체를 스프링이 실행될 때 만들어 주고 필요한 곳에 주입한다.

Spring이 모든 의존성 객체를 Spring이 실행 될 때 다 만들어 주고 필요한 곳에 주입 시켜줌으로써 Bean들은 싱글톤 패턴의 특징을 갖습니다.

  • Bean : Spring IOC 컨테이너가 관리하는 객체

참조 및 내용출처 : 블로그

 

[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유

1. 의존성 주입(Dependency Injection)의 개념과 필요성 [ 의존성 주입(Dependency Injection) 이란? ] Spring 프레임워크는 3가지 핵심 프로그래밍 모델을 지원하고 있는데, 그 중 하나가 의존성 주입(Dependency Inj

mangkyu.tistory.com

 

Layered Architecture 란 ?

복잡한 애플리케이션을 여러 개의 계층으로 나누어 설계하고 개발하는 것 !

각 계층을 전문적으로 다룬다는 목적이 있다. 레이어드 아키텍쳐는 구성요소들이 수평적인 레이어로 조직화되어 있는 다층 구조이며, 모든 구성요소가 연결되어 있지만 독립적이라 말할 수 있다.

  • Presentation Layer

클라이언트로 응답을 다시 보내는 역할을 담당하는 모든 클래스가 포함된다.

  • Business Layer

시스템을 구현해야하는 로직들을 해당 레이어에서 구현하게 된다. 접근성 , 보안 , 인증 , 유효성 검사 와 같은 로직들이 해당 계층에서 발생한다.

  • Persistence Layer

데이터베이스에서 데이터를 저장, 수정, 읽는 등 데이터베이스와 관련된 로직을 구현한다. DAO(Data Access Object)presentation, ORM(Object Relational Mappings) 등을 포함한다.

  • Database Layer

데이터 베이스가 저장되는 레이어

특징

레이어드 아키텍쳐는 하위 계층에만 의존한다. 위 그림 계층 구조에서 비즈니스 레이어는 프레젠테이션 레이어로부터 독립적이고 , 퍼시스턴스 레이어에는 의존적이다. 그래서 하위계층의 변경에 있어서는 상위계층은 신경쓰지 않아도 되는 장점이 있다. 이 특징으로 각 계층의 역할들이 명확해지며, 개발과 테스트가 용이해진다.

 

Entity와 DTO란?

Entity

실제 DB 테이블과 매핑되는 핵심 클래스로, DB 테이블에 존재하는 컬럼들을 필드로 가지는 객체

DTO (Data Transfer Object)

계층간 데이터 교환이 이루어 질 수 있도록 하는 객체

 

Entity와 DTO를 분리하는 이유 ⇒ 관심사 분리!!

  • 관심사의 분리 : Entity와 DTO를 분리해야 하는 가장 근본적인 이유는 관심사가 서로 다르기 때문! (*관심사의 분리(separation of concerns, SoC)는 소프트웨어 분야의 오래된 원칙 중 하나로써, 서로 다른 관심사들을 분리하여 변경 가능성을 최소화하고, 유연하며 확장가능한 클린 아키텍처를 구축하도록 도와줌)
  • Entity의 값이 변하면 Repository 클래스의 Entity Manager의 flush가 호출될 때 DB에 값이 반영되고, 이는 다른 로직들에도 영향 미친다. View와 통신 하면서 필연적으로 데이터의 변경이 많은 DTO클래스를 분리해주어야 한다
  • 도메인 설계가 아무리 잘 되있다 해도 Getter만을 이용해서 원하는 데이터를 표시하기 어려운 경우가 발생할 수 있는데, 이 경우에 Entity와 DTO가 분리되어 있지 않다면 Entity안에 Presentation을 위한 필드나 로직이 추가되게 되어 객체 설계를 망가뜨리게 된다. 때문에 이런 경우에는 분리한 DTO에 Presentation로직 정도를 추가해서 사용하고, Entity에는 추가하지 않아서 도메인 모델링을 깨뜨리지 않는다.

 

Singleton Pattern이란?

  • 싱글톤 패턴이란 인스턴스를 1개로 제한하며 어디서든 접근 할 수 있도록하는 객체 생성 디자인 패턴이다. 싱글톤 클래스는 본인을 호출하는 static 메소드를 가지고 있으며, 이 메소드를 호출하면 본인을 반환하도록 설계된다.
  • 객체 지향 프로그래밍에서는 모든 객체들은 라이프 사이클(객체가 생성되고 GC에 의해 삭제되기 까지)을 가지고 있다. 객체를 여러개 만들지 않고 1개만 만들고 공유하고 싶을 때 사용할 수 있는 패턴이 싱글톤 패턴이다. (ex. DB의 Transaction을 관리하는 클래스)

Singleton Pattern의 문제점

  1. 싱글톤 패턴을 구현하는 코드 자체가 많이 들어간다.
  2. 의존 관계 클라이언트가 추상화 클래스에 의존하는 게 아니라 구체 클래스에 의존하게 되면서 객체 지향 설계 5원징인 SOILD 중 DLP(의존관계 역전 원칙)를 위한하고 OCP(개방-폐쇄 원칙)을 위반할 가능성이 높다.
  3. 내부 속성을 변경하고 초기화하는게 어렵고 private 생성자로 자식 클래스를 만들기가 어렵다.

Spring에서의 Singleton Pattern

  • 스프링에서는 클래스 자체에 의해서 객체를 생성하지 않고 스프링 컨테이너에 의해 구현이 된다.
  • 스프링 컨테이너는 싱글톤 패턴의 문제를 해결하면서 싱글톤 패턴을 적용하지 않아도 객체의 인스턴스를 싱글톤으로 관리한다.
  • 스프링의 싱글톤 레지스트리 - 싱글톤 패턴의 단점을 보완하기 위해 나온것 - 스프링 컨테이너가 싱글톤 컨테이너 역할을 하고 싱글톤 객체를 생성하고 관리하는 기능
    • 스프링 컨테이너 기능 덕분에 싱글톤 패턴의 단점을 해결하면서 싱글톤으로 유지할 수 있다.
  • 결국 스프링 Bean이 싱글톤으로 관리되는 Bean이다

 

Factory Method Pattern

  • 객체 생성 처리를 서브 클래스로 분리하여 처리하도록 하는 캡슐화 패턴이다. 즉, 객체의 생성 코드를 별도의 클레스/메소드로 분리함으로써 객체 생성의 변화에 대비하여 유용하게 사용할 수 있다.
  • Factory Method Pattern의 장단점
    • 장점
      1. 비슷한 성격의 객체를 인터페이스를 통해 하나로 관리할 수 있다. (코드가 간결해진다.)
      2. 비슷한 유형의 객체가 생성되어도 implement를 통해 쉽게 추가할 수 있다.
    • 단점
      • 제품 클래스가 바뀔 때 마다 새로운 서브 클래스를 작성해야 한다.
    • 클래스가 많아지기 때문에 클래스 계층도 커질 수 있다.

Factory Method Pattern의 구조

  1. Product는 인터페이스를 선언한다. 인터페이스는 생성자와 자식 클래스들이 생성할 수 있는 모든 객체에 공통이다.
  2. Concrete Prodect들은 제품 인터페이스의 다양한 구현들이다.
  3. Creator 클래스는 새로운 제품 객체들을 반환하는 Factory Method를 선언한다. 이 때 Factory Method의 반환 유형이 Product 인터페이스와 일치해야한다.
  4. ConcreteCreator들은 기초 Factory Method를 오버라이드(재정의)하여 다른 유형의 Product를 반환하게 하도록 한다.
  • Factory Method는 항상 새로운 인스턴스를 생성해야 할 필요가 없다. 기존 객체들을 캐시, 객체 풀 또는 다른 소스로부터 반환할 수 있다.

 

Proxy Pattern

  • 어떤 객체에 대한 접근을 제어하기 위한 용도로, 실제 객체의 메소드를 호출하면 그 호출을 중간에 가로채는 패턴이다.
  • 즉, 제어 흐름을 조정하기 위해 중간에 대리자를 두는 패턴
  • 스프링에서는 AOP를 통해서 이런 공통적인 기능들을 별도로 분리해 필요한 곳에서 재사용이 가능 
    • AOP(Aspect Oriented Programming)이란?
    • 관점 지향 프로그래밍 - 공통 기능과 핵심 기능을 분리시켜 공통 기능을 계속 재활용하여 사용하는 방식 (main기능이 아닌 기능(Logging/Transcation)을 묶음으로 하여 Main 기능을 잘 구성할 수 있게 해주는 방식)

Proxy Pattern의 구조

  1. Client가 해당 함수를 직접 호출하는 것이 아닌 Proxy를 호출한다.
  2. Proxy Class에서 실제 Class를 호출한다.( Proxy Class는 실제로 호출할 Class를 이미 가지고 있다.
  3. 실제 Class에서 반환 받은 값을 Client에게 반환한다.
  • Proxy Pattern의 장단점
    • 장점
      • 사이즈가 큰 객체가 로딩되기 전에도 proxy를 통해 참조를 할 수 있다.(이미지, 동영상 등의 로딩에서 반응성 혹은 성능 향상 - 가상 프록시)
      • 실제 객체의 public, protected 메소드들을 숨기고 인터페이스를 통해 노출시킬 수 있다.( 안정성 - 보호 프록시 )
      • 로컬에 있지 않고 떨어져 있는 객체를 사용할 수 있다. (RMI, EJB 의 분산처리 등 - 원격 프록시)
      • 원래 객체의 접근에 대해서 사전처리를 할 수 있다. (객체의 레퍼런스 카운트 처리 - 스마트 프록시 )
      • 원본 객체의 참조만 필요할 때는 원본 객체를 사용하다가, 최대한 늦게 복사가 필요한 시점에 원본 객체를 복사하여 사용한다. (Concurrent package의 CopyInWriteArrayList - 변형된 가상 프록시)
    • 단점
      • 객체를 생성할 때 한단계를 거치게 되므로, 빈번한 객체 생성이 필요한 경우 성능이 저하될 수있다.
      • 프록시 안에서 실제 객체 생성을 위해서 thread가 생성되고 동기화가 구현되야하는 경우 서능이 저하되고 로직이 난해해질 수 있다.

디폴트 메서드와 static 메서드

디폴트 메서드와 static 메서드

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

 

디폴트 메서드가 기존의 메서드와 충돌할 때 해결책

  • 여러 인터페이스와 디폴트 메서드 간의 충돌
    • 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩 해야함
  • 디폴트 메서드와 조상 클래스의 메서드 간의 충돌
    • 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시됨

인터페이스 interface

  • 추상 메서드의 집합
  • 구현된 것이 전혀 없는 설계도. 껍데기 (모든 멤버가 public)
  • 기본 설계도
  • 다른 클래스를 작성하는데 도움이 될 목적으로 작성
  • 추상클래스와 인터페이스의 차이
    • 추상클래스는 일부가 구현된 미완성 설계도
    • 인터페이스는 아무것도 구현된 것도 없고 밑그림만 그려져있는 기본 설계도
interface 인터페이스이름 {
	public static final 타입 상수이름 = 값; //상수
    public abstract 메서드이름(매개변수목록); //추상메서드
}

//인터페이스의 모든 메소드는 public이고 final이고 abstract 여서 생략 가능

 

인터페이스의 상속

  • 인터페이스의 조상은 인터페이스만 가능(Object가 최고 조상이 아님)
  • 다중 상속이 가능 (추상메서드는 충돌해도 문제 없음)
interface Fightable extends Movable, Attackable {}
interface Movable {
	/** 지정된 위치(x,y)로 이동하는 기능의 메서드 */
    void move(int x, int y);
 }
 
 interface Attackable {
 	/** 지정된 대상(u)을 공격하는 기능의 메서드 */
    void attack(Unit u);
}

 

인터페이스의 구현

  • 인터페이스에 정의된 추상 메서드를 완성하는 것
class 클래스이름 implements 인터페이스이름 {
        // 인터페이스에 정의된 추상메서드를 모두 구현해야 한다
}
  • 구현한다는 의미의 키워드 'implements'를 사용함
class Fighter implements Fightable {
	public void move(int x, int y) { /*내용 생략 */}
    public void attack(Unit u)     { /*내용 생략 */} // 몸통 완성
}

//Fighter 클래스는 Fightable 인터페이스를 구현했다.
  • 추상클래스 완성과 동일; 키워드만 다름
  • 일부만 구현하는 경우, 클래스 앞에 abstract를 붙어야 함

 

  • 인터페이스란?
    • 추상 메서드의 집합
  • 인터페이스의 구현이란?
    • 인터페이스의 추상메서드 몸통{} 만들기(미완성 설계도 완성하기)
  • 추상 클래스와 인터페이스의 공통점은?
    • 추상 메서드를 가지고 있다 (미완성 설계도)
  • 추상 클래스와 인터페이스의 차이점은?
    • 인터페이스는 iv를 가질 수 없다

 

 

인터페이스를 이용한 다형성

  • 인터페이스도 구현클래스의 부모
  • 인터페이스 타입 매개변수는 인터페이스 구현한 클래스의 객체만 가능
  • 인터페이스를 메서드를 리턴타입으로 지정할 수 있다
abstract class Unit2 {
    int x, y;
    abstract void move(int x, int y);
    void stop() {
        System.out.println("멈춥니다.");
    }
}

interface Fightable { //인터페이스의 모든 메서드는 public abstract. 예외 없이
    void move (int x, int y); // public abstract가 생략됨
    void attack(Fightable f); // public abstract가 생략됨
}

class Fighter extends Unit2 implements Fightable{
    //오버라이딩 규칙: 조상(public) 보다 접근제어자가 좁으면 안된다.
    public void move (int x, int y) {
        System.out.println("["+x+","+y+"]로 이동");
    }
    public void attack(Fightable f){
        System.out.println(f+"를 공격");
    }

}

public class FighterTest {
    public static void main(String[] args) {
//      Fighter f = new Fighter();
        Unit2 u = new Fighter(); //Unit2에는 attack()이 없어서 호출불가
        Fightable f = new Fighter();
        u.move(100, 200);
//        u.attack(new Fighter());  //Unit2에는 attack()이 없어서 호출불가
        u.stop();

        f.move(100, 200);
        f.attack(new Fighter());
//        f.stop();                 //Fightable에는 stop()이 없어서 호출불가

    }
}

 

인터페이스의 장점

  • 두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 '중간 역할'을 한다
  • GUI - Graphic User Interface
  • 선언(설계, 껍데기)와 구현(알맹이)을 분리시킬수 있게 함
    • 변경에 유리하고 유연한 코드가 됨
    • 인터페이스 덕분에 B가 변경되어도 A는 안바꿀 수 있게 됨 -> 느슨한 결합
    • 의존도가 낮아짐
  • 개발 시간 단축 가능
  • 변경에 유리한 유연한 설계 가능
  • 표준화가 가능
  • 서로 관계없는 클래스들을 관계를 맺어줄 수 있음
  • 다중상속 가능
class A{
    public void method(I i) { //인터페이스 I를 구현한 넘들만 들어와라
        i.method();
    }
}


// B클래스의 선언과 구현을 분
interface I {
    public  void method();
}

class B implements I{
    public void method(){
        System.out.println("B클래스의 메서드");
    }
}

class C implements I{
    public void method(){
        System.out.println("C클래스의 메서드");
    }
}

public class InterfaceTest {
    public static void main(String[] args) {
        A a = new A();
        a.method(new C()); // A가 B를 사용(의존)

    }
}

자바의정석 남궁성

 

추상클래스 (abstract class)

- 미완성 설계도, 미완성 메서드를 갖고 있는 클래스

- 추상메서드는 몸통{}이 없는 미완성 메서드

- 다른 클래스 작성에 도움을 주기 위한 것 -> 인스턴스 생성 불가

abstract class Player{
        abstract void play(int pos);  //추상메서드 (몸통{} 이 없는 미완성 메서드)
        abstract void stop();     // 추상메서드
}

- 상속을 통해 추상 메서드를 완성해야 인스턴스 생성가능

class AudioPlayer extends Player{
         void play(int pose) { /*내용 생략*/}  //추상메서드를 구현
         void stop() { /* 내용 생략*/ }             //추상메서드를 구현

 

추상 메서드(abstract method)

-미완성 메서드, 구현부 {}가 없는 메서드

abstract 리턴타입 메서드이름();

- 꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우 사용

 

 

abstract class Player {  //추상 클래스
    abstract void play(int pos);  //추상 메서드
    abstract void stop();  //추상 메서드 (선언부만 있고 구현부{}가 없는 메서드)

}

//추상 클래스는 상속을 통해 완성해야 객체 생성가능
class AudioPlayer extends  Player {
    @Override
    void play(int pos) {
        System.out.println(pos+"위치부터 play 합니다");
    }

    @Override
    void stop() {
        System.out.println("재생을 멈춥니다.");
    }
}


public class PlayerTest {

    public static void main(String[] args) {
//        Player p = new Player(); // 추상 클래스의 객체를 생성
//        AudioPlayer ap = new AudioPlayer();
        Player ap = new AudioPlayer(); //다형성
        ap.play(100);
        ap.stop();
    }
}

 

추상클래스의 작성

- 여러 클래스에 공통적으로 사용될 수 있는 추상클래스를 바로 작성하거나 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만든다


public class Ex7_10 {
    public static void main(String[] args) {
//        Unit[] group = new Unit[]{new Marine(), new Tank(), new Dropship()};
        Unit[] group = new Unit[3];
        group[0] = new Marine();
        group[1] = new Tank();
        group[2] = new Dropship();
        for(int i = 0; i < group.length; ++i)
            group[i].move(100, 200);
    }

}

abstract class Unit {
    int x, y;
    abstract void move(int x, int y);
    void stop() {/*현재 위치에 정지*/}
}

class Marine extends Unit { //보병
    void move(int x, int y) {
        System.out.println("Marine[x="+x+",y="+y+"]");
    }
    void stimPack() {/*스팀팩을 사용한다. */}
}

class Tank extends Unit { //탱크
    @Override
    void move(int x, int y) {
        System.out.println("Tank[x="+x+",y="+y+"]");
    }
    void changeMod() { /*공격모드를 변환한다.*/}
}

class Dropship extends Unit { //탱크
    @Override
    void move(int x, int y) {
        System.out.println("Dropship[x="+x+",y="+y+"]");
    }
    void change() { /*공격모드를 변환한다.*/}
}

- 추상화된 코드는 구체화된 코드보다 유연; 변경에 유리함

 

 

자바의 정석 기초편

instanceof 연산자

  • 참조변수의 형변환 가능여부 확인에 사용 -> 가능하면 true return
  • 형변환 전에 반드시 instanceof로 확인해야함
  • 참조변수 형변환은 왜?
    • -> 참조변수를 변경함으로써 사용할 수 있는 멤버의 갯수를 조절하기 위해서
    • 타입 일치시키려고

 

매개변수의 다형성

  • 다형적 매개변수
  • 하나의 배열로 여러종류 객채다루기
  • 참조형 매개변수는 메서드 호출시, 자신과 같튼 타입 또는 자손타입의 인스턴스를 넘겨줄 수 있다.

 

여러 종류의 객체를 배열로 다루기

  • 조상타입의 배열에 자손들의 객체를 담을 수 있다

 

Vector class에는 모든 종류의 객체 저장 가능

object[]

 

동영상 예시를 보면 도움이 된다.

 

 

 

혼공자 자동타입변환 형변환

자동타입변환 promotion

  • 프로그램 실행 도중에 자동적으로 타입 변환이 일어남

 

부모 타입 변수 = 자식 타입;

 

  • 자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있음
  • 바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이면 자동 타입 변환이 일어날 수 있음
  • 부모 타입으로 자동타입 변환된 이후 부모 클래스에 선언된 필드와 메소드만 접근 가능
  • 변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스만 가능
  • 예외-> 메소드가 자식 클래스에서 재정의된 경우 자식 클래스의 메소드가 대신 호출됨

 

필드의 다형성

  • 다형성을 구현하기 위해서 부모타입으로 자동 타입 변환이 필요함
  • 필드의 타입을 부모 타입으로 선언하면 다양한 자식 객체들이 저장될 수 있기 때문에 필드 사용 결과가 달라질 수 잇음 -> 필드의 다형성
  • 객체들이 다른 객체로 교체 될 수 있어야 함
  • 자동 타입 변환을 이용해서 필드값을 교체함으로써 메소드를 수정하지 않아도 다양한 실행결과를 얻게 됨 -> 필드의 다형성

 

매개 변수의 다형성

  • 자동 타입 변환은 주로 메소드를 호출할 때 발생
  • 매소드 호출시 매개 변수의 타입과 동일한 매개값을 지정하는 것이 정석이지만 매개값을 다양화 하기 위해 매개 변수에 자식 객체를 저장할 수도 있음
  • 매개 변수 타입이 클래스일 경우, 해당 클래스의 객체뿐만 아니라 자식 객체까지도 매개값으로 사용 가능

 

강제 타입 변환 (casting)

  • 자식타입 변수 = (자식타입) 부모타입;
  • 자식타입이 부모 타입으로 자동 타입 변환 된 후 다시 자식 타입으로 변환할 때 사용
  • 자식에 선언된 필드와 메소드를 꼭 사용해야 할 때 강제 타입 변환을 해서 다시 자식 타입으로 변환 후 자식의 필드와 메소드 사용

 

객체 타입 확인 instanceof 연산자

  • 어떤 객체가 어떤 클래스의 인스턴스인지 확인하기 위해 사용

 

boolean result = 좌항(객체) instanceof 우향(타입)

 

  • 매개값의 타입을 조사할 때 주로 사용
  • 메소드 내에서 강제 타입 변환이 필요한 경우 매개값이 어떤 객체인지 instanceof 연산자로 확인하고 안전하게 강제 타입 변환
  • 타입 확인 안하고 강제 타입 변환 시도시 ClassCastException 발생할 수 있음

 

확인문제

  • 자식 객체는 부모 타입으로 자동 타입 변환 된다 (o)
  • 부모 객체는 항상 자식 타입으로 강제 타입 변환 된다 (x)
  • 자동 타입 변환을 이용해서 필드와 매개 변수의 다형성을 구현한다. (o)
  • 강제 타입 변환 전에 instanceof 연산자로 변환 가능한지 검사하는 것이 좋다 (o)

 

혼자공부하는자바 상속

  • 상속을 이용하면 부모 클래스의 수정으로 모든 자식 클래스들도 수정되는 효과를 가져오기 때문에 유지 보수 시간을 최소화 가능

 

클래스 상속

  • 프로그램에서는 자식이 부모를 선택
class 자식 클래스 extends 부모클래스 {

//필드

//생성자

//메소드

}

 

  • 단 하나의 부모 클래스만 상속 가능
  • 부모 클래스에서 private 접근 제한 필드와 메소드는 상속 대상 x
  • 다른 패키지라면 default 접근 제한 필드와 메소드는 상속 대상 x

 

부모 생성자 호출

  • 모든 객체는 클래스의 생성자를 호출해야만 생성
  • 부모 생성자는 자식 생ㅎ성자의 맨 첫출에서 호출됨
  • super()는 부모의 기본 생성자를 호출함 ->컴파일러가 자동 생성

 

메소드 재정의 (오버라이딩 overriding)

  • 부모의 메소드와 동일한 시그니처 (리턴타입, 메소드 이름, 매개 변수 목록)을 가저야 함
  • 접근 제한을 더 강하게 재정의할 수 없음
  • 새로운 예외를 throws할 수 없음
  • @Override 어노테이션을 붙여주면 컴파일러가 확인도 해줌 -> 안붙여도 상관 x but 추천

 

부모 메소드 호출

  • super.부모메소드()
  • 자식 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출할 때 사용

 

final 클래스와 final 메소드

  • 상속할 수  없는 final 클래스
  • final 클래스는 부모 클래스가 될 수 없음
  • 재정의할 수 없는 final 메소드
  • final 메소드는 자식 클래스에서 재정의 할 수 없음

 

확인문제

  • 자바는 다중 상속을 허용한다. (x)
  • 부모의 메소드를 자식 클래스의 재정의(오버라이딩)할 수 있다. (o)
  • 부모의 private 접근 제한을 갖는 필드와 메소드는 상속의 대상이 아니다 (o)
  • protected 멤버는 같은 패키지의 모든 클래스와 다른 패키지의 자식클래스만 접근할 수 있다 (o)
  • 부모의 메소드는 숨김 효과가 나타난다 (o)
  • 재정의 시 접근 제한을 더 강하게 할 수 있다 (x)
  • @Override를 붙이면 컴파일러가 재정의를 확인한다 (o)
  • 부모 메소드를 호출하고 싶다면 super 키워드를 사용할 수 있다 (o)

 

final 클래스, final 필드, final 메소드에 관한 설명 o,x 

  • 모두 상속과 관련이 있다 (x) -> 필드는 상속과 관련이 없음
  • final 메소드를 가진 클래스는 부모 클래스가 될 수 없다 (x) -> 재정의 할 수 없다
  • final 메소드는 재정의 할 수 없다 (o)
  • final 클래스는 final 필드가 반드시 있어야 한다 (x)

 

 

+ Recent posts