<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>zzanhong.log</title>
        <link>https://velog.io/</link>
        <description>한 줄 소개</description>
        <lastBuildDate>Fri, 23 Sep 2022 09:33:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>zzanhong.log</title>
            <url>https://velog.velcdn.com/images/chanhong-dev/profile/4afd7c89-9b02-4fb1-a511-f046dcf04f83/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. zzanhong.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/chanhong-dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Filter VS Interceptor]]></title>
            <link>https://velog.io/@chanhong-dev/Filter-VS-Interceptor</link>
            <guid>https://velog.io/@chanhong-dev/Filter-VS-Interceptor</guid>
            <pubDate>Fri, 23 Sep 2022 09:33:09 GMT</pubDate>
            <description><![CDATA[<ul>
<li>자바, 스프링 웹 개발을 하다보면, <strong>공통적으로 처리해야할 로직</strong>들이 존재한다.</li>
<li>로그인 관련 처리, 권한 체크, XSS 방어, 접속 OS처리, 로그 등..</li>
<li>공통된 부분은 따로 빼서 구현 및 관리 하는 것이 유리하다.</li>
</ul>
<h3 id="공통처리를-위해-활용-가능한-3가지">공통처리를 위해 활용 가능한 3가지</h3>
<ol>
<li>Filter</li>
<li>Interceptor</li>
<li>AOP</li>
</ol>
<h2 id="spring에서의-흐름">Spring에서의 흐름</h2>
<p><img src="https://velog.velcdn.com/images/chanhong-dev/post/c7c0f9c2-6610-471d-9579-ca0801feb570/image.png" alt=""></p>
<ul>
<li>Interceptor와 Filter는 <code>Servlet 단위</code>에서 실행</li>
<li>AOP는 메소드 앞에 <code>Proxy패턴의 형태</code>로 실행</li>
<li>Filter → Interceptor → AOP → Interceptor → Filter 순</li>
</ul>
<h2 id="filter필터">Filter(필터)</h2>
<ul>
<li>J2EE 표준 스펙 기능</li>
<li>디스패처 서블릿(Dispatcher Servlet)에 요청이 전달 되기 전/후에 패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공</li>
<li>웹 컨테이너에서 동작</li>
</ul>
<p><img src="https://velog.velcdn.com/images/chanhong-dev/post/d2b04ace-815e-4849-b057-caf910eadd83/image.png" alt=""></p>
<h3 id="filter의-메소드">Filter의 메소드</h3>
<ul>
<li><code>init()</code> : 필터 인스턴스 초기화</li>
<li><code>doFilter()</code> : 전/후 처리</li>
<li><code>destroy()</code> : 필터 인스턴스 종료</li>
</ul>
<pre><code class="language-java">public interface Filter {

    public default void init(FilterConfig filterConfig) throws ServletException {}

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException;

    public default void destroy() {}
}</code></pre>
<h2 id="필터의-용도">필터의 용도</h2>
<ul>
<li>공통된 보안 및 인증/인가 관련작업</li>
<li>모든 요청에 대한 로깅 또는 감사</li>
<li>이미지/데이터 압축 및 문자열 인코딩</li>
<li>Spring과 분리 되어야 하는 기능</li>
</ul>
<hr>
<h2 id="interceptor인터셉터">Interceptor(인터셉터)</h2>
<ul>
<li>Spring에서 제공하는 기술</li>
<li>디스패처 서블릿(Dispatcher Servlet)이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능</li>
<li>스프링 컨텍스트에서 동작</li>
<li>핸들러 매핑의 결과로 실행체인(HandlerExecutionChain)이 나옴.
→ 인터셉터가 등록되어 있다면 순차적으로 인터셉터들을 거쳐 컨트롤러가 실행되도록 함.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/chanhong-dev/post/8c1fcd12-ef12-44b9-b308-fc7d4410e78a/image.png" alt=""></p>
<h3 id="인터셉터의-메소드">인터셉터의 메소드</h3>
<ul>
<li><code>preHandler()</code> : 컨트롤러 메소드가 실행되기 전</li>
<li><code>postHandler()</code> : 컨트롤러 메소드 실행 직 후 / view 페이지 렌더링 전</li>
<li><code>afterCompletion()</code> : view 페이지 렌더링 후</li>
</ul>
<pre><code class="language-java">public interface HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {

        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
        @Nullable Exception ex) throws Exception {
    }
}</code></pre>
<h2 id="인터셉터의-용도">인터셉터의 용도</h2>
<ul>
<li>세부적인 보안 및 인증/인가 공통 작업</li>
<li>API 호출에 대한 로깅 또는 감사</li>
<li>Controller로 넘겨주는 정보 가공</li>
</ul>
<hr>
<h2 id="필터-vs-인터셉터">필터 VS 인터셉터</h2>
<p><img src="https://velog.velcdn.com/images/chanhong-dev/post/8657e8ce-5287-485f-ae52-e76ad7a39689/image.png" alt=""></p>
<h3 id="requestresponse-조작-여부">Request/Response 조작 여부</h3>
<ul>
<li>필터는 가능하지만, 인터셉터는 불가능</li>
<li>조작이란 내부 상태를 변경하는 것이 아니라 다른 객체로 바꿔지기가 가능하다는 것</li>
</ul>
<p><strong>필터</strong></p>
<pre><code class="language-java">public MyFilter implements Filter {

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
        // 개발자가 다른 request와 response를 넣어줄 수 있음
        chain.doFilter(request, response);       
    }

}</code></pre>
<p><strong>인터셉터</strong></p>
<pre><code class="language-java">public class MyInterceptor implements HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // Request/Response를 교체할 수 없고 boolean 값만 반환할 수 있다.
        return true;
    }

}</code></pre>
<h2 id="reference">Reference</h2>
<p><a href="https://mangkyu.tistory.com/173">https://mangkyu.tistory.com/173</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Stream API]]></title>
            <link>https://velog.io/@chanhong-dev/Stream-API</link>
            <guid>https://velog.io/@chanhong-dev/Stream-API</guid>
            <pubDate>Wed, 17 Aug 2022 07:56:08 GMT</pubDate>
            <description><![CDATA[<h2 id="stream-api">Stream API</h2>
<pre><code class="language-java">List&lt;String&gt; names = new ArrayList&lt;&gt;();

names.add(&quot;chanhong&quot;);
names.add(&quot;pig&quot;);</code></pre>
<ul>
<li><p>연속된 데이터를 처리하는 연산(Operation)들의 모음</p>
</li>
<li><p>Functional in nature, 스트림이 처리하는 데이터 소스를 변경하지 않는다.</p>
<pre><code class="language-java">  Stream&lt;String&gt; stringStream = neames.stream().map(String::toUpperCase);

  names.forEach(System.out::println);</code></pre>
</li>
<li><p>스트림으로 처리하는 데이터는 오직 한번만 처리한다.</p>
</li>
<li><p>손 쉽게 병렬 처리할 수 있다. (<code>parallelStream()</code>)</p>
</li>
<li><p>중개 오퍼레이션은 근본적으로 lazy하다.</p>
</li>
</ul>
<h3 id="스트림-파이프라인">스트림 파이프라인</h3>
<ul>
<li>0 또는 다수의 중계 오퍼레이션과 한개의 종료 오퍼레이션으로 구성된다.</li>
<li>스트림의 데이터 소스는 오직 터미널 오퍼레이션을 실행할 때에만 처리한다.</li>
</ul>
<p><strong>중개 오퍼레이션</strong></p>
<ul>
<li>Stream을 리턴한다.</li>
</ul>
<p><strong>종료 오퍼레이션</strong></p>
<ul>
<li>Stream을 리턴하지 않는다.</li>
</ul>
<pre><code class="language-java">Stream&lt;String&gt; stringStream = names.stream().map((s) -&gt; {
        System.out.println(s);
        return s.toUpperCase();
});</code></pre>
<pre><code class="language-java">List&lt;String&gt; collect = names.stream().map((s) -&gt; {
        System.out.println(s);
        return s.toUpperCase();
}).collect(Collectors.toList());

collect.forEach(System.out::println</code></pre>
<h2 id="스트림-api-사용-예제">스트림 API 사용 예제</h2>
<pre><code class="language-java">List&lt;OnlineClass&gt; springClasses = new ArrayList&lt;&gt;();
        springClasses.add(new OnlineClass(1, &quot;spring boot&quot;, true));
        springClasses.add(new OnlineClass(2, &quot;spring data jpa&quot;, true));
        springClasses.add(new OnlineClass(3, &quot;spring mvc&quot;, false));
        springClasses.add(new OnlineClass(4, &quot;spring core&quot;, false));
        springClasses.add(new OnlineClass(5, &quot;rest api development&quot;, false));</code></pre>
<h3 id="걸러내기">걸러내기</h3>
<ul>
<li>Filter(Predicate)</li>
</ul>
<pre><code class="language-java">System.out.println(&quot;spring 으로 시작하는 수업&quot;);
        springClasses.stream()
                .filter(oc -&gt; oc.getTitle().startsWith(&quot;spring&quot;))
                .forEach(oc -&gt; System.out.println(oc.getId()));</code></pre>
<h3 id="변경하기">변경하기</h3>
<ul>
<li>Map 또는 FlatMap</li>
</ul>
<pre><code class="language-java">System.out.println(&quot;수업 이름만 모아서 스트림 만들기&quot;);
        springClasses.stream()
                .map(oc -&gt; oc.getTitle())
                .forEach(s -&gt; System.out.println(s));</code></pre>
<h3 id="생성하기">생성하기</h3>
<ul>
<li>generate 또는 Iterate</li>
</ul>
<pre><code class="language-java">System.out.println(&quot;10부터 1씩 증가하는 무제한 스트림 중에서 앞에 10개 빼고 최대 10개 까지만&quot;);
Stream.iterate(10, i -&gt; i + 1)
                .skip(10)
                .limit(10)
                .forEach(System.out::println);</code></pre>
<h3 id="제한하기">제한하기</h3>
<ul>
<li>limit 또는 skip</li>
</ul>
<pre><code class="language-java">System.out.println(&quot;자바 수업 중에 Test가 들어있는 수업이 있는지 확인&quot;);
        boolean test = javaClasses.stream().anyMatch(oc -&gt; oc.getTitle().contains(&quot;Test&quot;));
        System.out.println(test);

        System.out.println(&quot;스프링 수업 중에 제목에 spring이 들어간 것만 모아서 List로 만들기&quot;)
        List&lt;String&gt; spring = springClasses.stream()
                .map(OnlineClass::getTitle)
                .filter(t -&gt; t.contains(&quot;spring&quot;))
                .collect(Collectors.toList());
        spring.forEach(System.out::println);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[람다]]></title>
            <link>https://velog.io/@chanhong-dev/%EB%9E%8C%EB%8B%A4</link>
            <guid>https://velog.io/@chanhong-dev/%EB%9E%8C%EB%8B%A4</guid>
            <pubDate>Tue, 16 Aug 2022 08:37:16 GMT</pubDate>
            <description><![CDATA[<h2 id="함수형-인터페이스와-람다-표현식">함수형 인터페이스와 람다 표현식</h2>
<h3 id="함수형-인터페이스">함수형 인터페이스</h3>
<ul>
<li>추상 메소드를 딱 하나만 가지고 있는 인터페이스</li>
<li>SAM (Single Abstract Method) 인터페이스</li>
<li>@FunctionaInterface 애너테이션을 가지고 있는 인터페이스</li>
<li>추상 메소드만 1개이면 되고 <strong>static 메소드</strong>나 <strong>default 메소드</strong>는 여러 개 포함할 수 있습니다.</li>
<li>함수형 인터페이스를 이용해 <strong>람다 표현식</strong>을 구현(사용)할 수 있습니다.</li>
<li>람다를 구현하기 위해 함수형 인터페이스를 사용한다고 볼 수 있습니다.</li>
</ul>
<pre><code class="language-java">@FunctionalInterface
public interface RunSomething {
        void doit();

        static void printName() {
                System.out.println(&quot;이름&quot;);
        }

        default void printAge() {
                System.out.println(&quot;나이&quot;);
        }
}</code></pre>
<p><strong>자바 8 이전</strong> </p>
<pre><code class="language-java">//익명 내부 클래스 
RunSomething runSomething = new RunSomeThing() {
        @Override
        public void doit() {
                System.out.println(&quot;Hello&quot;);
        }
}</code></pre>
<p><strong>자바 8 이후</strong> </p>
<pre><code class="language-java">RunSomething runSomething = () -&gt; System.out.println(&quot;Hello&quot;);

RunSomething runSomething = () -&gt; {
        System.out.println(&quot;Hello&quot;);
        System.out.println(&quot;lambda&quot;);
}</code></pre>
<h3 id="자바에서-함수형-프로그래밍">자바에서 함수형 프로그래밍</h3>
<ul>
<li>함수를 First class object로 사용할 수 있다.</li>
<li>순수 함수 (Pure function)<ul>
<li>사이드 이펙트 만들 수 없다. (함수 밖에 있는 값을 변경하지 못한다.)</li>
<li>상태가 없다. (함수 밖에 정의되어 있는)</li>
</ul>
</li>
<li>고차 함수 (High-Order Function)<ul>
<li>함수가 함수를 매개변수로 받을 수 있고 함수를 리턴할 수도 있다.</li>
</ul>
</li>
<li>불변성</li>
</ul>
<h3 id="람다-표현식-lambda-expressions">람다 표현식 (Lambda Expressions)</h3>
<ul>
<li>함수형 인터페이스의 인스턴스를 만드는 방법으로 쓰일 수 있다.</li>
<li>코드를 줄일 수 있다.</li>
<li>메소드 매개변수, 리턴 타입, 변수로 만들어 사용할 수도 있다.</li>
<li>(인자 리스트) → {바디}</li>
</ul>
<p><strong>인자리스트</strong></p>
<ul>
<li>인자가 없을 때 : <code>( )</code></li>
<li>인자가 한개일 때 : <code>(one) 또는 one</code></li>
<li>인자가 여러개 일 때  : <code>(one, two)</code></li>
<li>인자의 타입은 생략가능, 컴파일러가 추론하지만 명시할 수도 있다.</li>
</ul>
<p><strong>바디</strong></p>
<ul>
<li>화살표 오른쪽에 함수 본문을 정의한다.</li>
<li>여러 줄인 경우에 <code>{ }</code>를 사용해서 묶는다.</li>
<li>한 줄인 경우에 <code>{ }</code> 생략 가능, <code>return</code>도 생략 가능</li>
</ul>
<h3 id="메소드-레퍼런스">메소드 레퍼런스</h3>
<ul>
<li>람다가 하는 일이 기존 메소드 또는 생성자를 호출하는 거라면, 메소드 레퍼런스를 사용해 매우 간결하게 표현할 수 있다.</li>
</ul>
<pre><code class="language-java">public class Greeting {
        private String name;

        public Greeting() {
        }

        public Greeting(String name) {
                this.name = name;
        }

        public String hello(String name) {
                return &quot;hello &quot; + name;
        }

        public static String hi(String name) {
                return &quot;hi &quot; + name;
        }
}</code></pre>
<pre><code class="language-java">UnaryOperator&lt;String&gt; hi = (s) -&gt; &quot;hi &quot; + s;

// 스태틱 메소드 참조
UnaryOperator&lt;String&gt; hi = Greeting::hi;

// 인스턴스 메소드 참조
Greeting greeting = new Greeting();
UnaryOperator&lt;String&gt; hi = greeting::hello;

// 기본 생성자
Supplier&lt;Greeting&gt; newGreeting = Greeting::new;

// 매개변수가 있는 생성자
Function&lt;String, Greeting&gt; newGreeting = Greeting::new;

Greeting greeting = newGreeting.get();</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[내부 클래스 ( Inner Class )]]></title>
            <link>https://velog.io/@chanhong-dev/%EB%82%B4%EB%B6%80-%ED%81%B4%EB%9E%98%EC%8A%A4-Inner-Class</link>
            <guid>https://velog.io/@chanhong-dev/%EB%82%B4%EB%B6%80-%ED%81%B4%EB%9E%98%EC%8A%A4-Inner-Class</guid>
            <pubDate>Thu, 11 Aug 2022 12:13:48 GMT</pubDate>
            <description><![CDATA[<p><strong>내부 클래스는 클래스 내에 선언된다는 점을 제외하고는 일반적인 클래스와 다르지 않다.</strong> </p>
<ul>
<li>두 클래스가 서로 긴밀한 관계가 있을 떄 내부 클래스를 사용한다.</li>
<li>내부 클래스에서 외부 클래스의 멤버들을 쉽게 접근할 수 있다.</li>
<li>외부에는 불필요한 클래스를 감춰서 코드의 복잡성을 줄일 수 있다는 장점이 있다.</li>
<li>서로 관련 있는 클래스를 논리적으로 묶어서 표현함으로써, 코드의 캡슐화를 증가시킨다.</li>
</ul>
<pre><code class="language-java">class A{    //외부클래스
    ...
    class B{    //내부클래스
        ...
    }
    ...
}</code></pre>
<ul>
<li>내부 클래스인 <code>B</code>는 외부 클래스인 <code>A</code>를 제외하고는 다른 클래스에서 잘 사용되지 않는 것이어야 한다.</li>
</ul>
<h3 id="내부-클래스의-종류와-특징">내부 클래스의 종류와 특징</h3>
<p><img src="https://velog.velcdn.com/images/chanhong-dev/post/aa83d4e6-abec-4722-bdcd-df29b1c284a2/image.png" alt=""></p>
<h3 id="내부-클래스의-제어자와-접근성">내부 클래스의 제어자와 접근성</h3>
<ul>
<li>내부 클래스 중 스태틱 클래스(static class)만 <code>static 멤버</code>를 가질 수 있다.</li>
<li><code>final</code>과 <code>static</code>이 동시에 붙은 변수는 상수 이므로 모든 클래스에 정의가 가능하다.</li>
<li><code>인스턴스 클래스</code>와 <code>스태틱 클래스</code>는 외부 클래스의 멤버변수와 같은 위치에 선언되며, 또한 멤버 변수와 같은 성질을 가진다.</li>
</ul>
<hr>
<h3 id="익명-클래스anonymous-class">익명 클래스(Anonymous class)</h3>
<pre><code class="language-java">public class Example {

    interface MyInterface {
        void doSomething();
    }

    public static void main(String[] args) {

        MyInterface myClass = new MyInterface() {
            @Override
            public void doSomething() {
                System.out.println(&quot;doSomething&quot;);
            }
        };
        myClass.doSomething();
    }
}</code></pre>
<ul>
<li>클래스의 선언과 객체의 생성을 동시에 하기 때문에 단 한 번만 사용될 수 있고 오직 하나의 객체만을 생성할 수 있는 <code>일회용 클래스</code>이다.</li>
<li>이름이 없기 때문에 생성자도 가질 수 없다.</li>
<li>단 하나의 클래스를 상속 받거나 단 하나의 인터페이스만을 구현할 수 있다.</li>
<li>익명 클래스는 이름이 없기 때문에 <code>외부클래스명$숫자.class</code> 형식으로 클래스 파일명이 결정된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[default 메소드]]></title>
            <link>https://velog.io/@chanhong-dev/default-%EB%A9%94%EC%86%8C%EB%93%9C</link>
            <guid>https://velog.io/@chanhong-dev/default-%EB%A9%94%EC%86%8C%EB%93%9C</guid>
            <pubDate>Tue, 09 Aug 2022 12:50:37 GMT</pubDate>
            <description><![CDATA[<h3 id="default-메소드의-등장">default 메소드의 등장</h3>
<ul>
<li>인터페이스는 기능에 대한 선언만 가능, 실제 구현 로직은 포함될 수 없다.</li>
<li>자바 8부터 등장한 <code>default 메소드</code>는 인터페이스 내부에서도 로직이 포함된 메소드를 선언할 수 있게 한다.</li>
</ul>
<pre><code class="language-java">interface MyInterface { 
    default void printHello() { 
        System.out.println(&quot;Hello World&quot;); 
    } 
}</code></pre>
<ul>
<li>이를 구현하는 클래스는 <code>@Override</code> 가능하다.</li>
</ul>
<h3 id="default-메소드-등장-이유">default 메소드 등장 이유</h3>
<ul>
<li>자바 기본서 ‘자바의 신’에서는 <code>default 메소드</code>에 대한 존재 이유를 아래와 같이 설명한다.</li>
</ul>
<aside>
💡 ...(중략) ... 바로 "하위 호환성"때문이다. 예를 들어 설명하자면, 여러분들이 만약 오픈 소스코드를 만들었다고 가정하자. 그 오픈소스가 엄청 유명해져서 전 세계 사람들이 다 사용하고 있는데, 인터페이스에 새로운 메소드를 만들어야 하는 상황이 발생했다. 자칫 잘못하면 내가 만든 오픈소스를 사용한 사람들은 전부 오류가 발생하고 수정을 해야 하는 일이 발생할 수도 있다. 이럴 때 사용하는 것이 바로 default 메소드다. (자바의 신 2권)

</aside>

<ul>
<li><strong>인터페이스의 기본 구현을 그대로 상속하므로 인터페이스에 자유롭게 새로운 메소드를 추가할 수 있게 된다.</strong></li>
<li>호환성을 유지하면서 API를 바꿀 수 있다.</li>
</ul>
<ol>
<li>바이너리 호환성 : 변경 이후에도 에러 없이 기존 바이너리가 실행될 수 있는 상황</li>
<li>소스 호환성 :  코드를 고쳐도 기존 프로그램을 성공적으로 재컴파일할 수 있는 상황</li>
<li>동작 호환성 : 코드를 바꾼 다음에도 같은 입력값이 주어지면 같은 동작을 하는 상황</li>
</ol>
<h3 id="default-메소드의-규칙">default 메소드의 규칙</h3>
<ol>
<li>클래스가 항상 이긴다. 클래스나 슈퍼클래스에서 정의한 메소드가 디폴트 메소드보다 우선권을 갖는다. </li>
<li>1번 규칙 이외의 상황에서는 서브 인터페이스가 항상 이긴다. 즉, B가 A를 상속받는 다면 B가 A를 이긴다. </li>
<li>여전히 디폴트 메소드의 우선순위가 결정되지 않았다면 여러 인터페이스를 상속받은 클래스가 명시적으로 디폴트 메소드를 오버라이드 하고 호출해야한다. </li>
</ol>
<pre><code class="language-java">public interface A {
    default void hello() {
        System.out.println(&quot;Hello from A&quot;);
    }
}

public interface B extends A{
    default void hello() {
        System.out.println(&quot;Hello from B&quot;);
    }
}

public class C implements B, A {
    public static void main(String args[]) {
        new C().hello();  //&quot;Hello from B&quot;가 출력됨!
    }
}</code></pre>
<h3 id="default-메소드의-활용">default 메소드의 활용</h3>
<ol>
<li>선택형 메소드</li>
<li>동작 다중 상속</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바 공부 목록]]></title>
            <link>https://velog.io/@chanhong-dev/%EC%9E%90%EB%B0%94-%EA%B3%B5%EB%B6%80-%EB%AA%A9%EB%A1%9D</link>
            <guid>https://velog.io/@chanhong-dev/%EC%9E%90%EB%B0%94-%EA%B3%B5%EB%B6%80-%EB%AA%A9%EB%A1%9D</guid>
            <pubDate>Mon, 08 Aug 2022 13:42:22 GMT</pubDate>
            <description><![CDATA[<p><del>인터페이스 vs 추상 클래스</del>,
<del>내부 클래스</del>,
인터페이스(심화), 
인터셉터 vs 필터,
제네릭,
<del>default키워드</del>
다이나믹 메소드 디스패치 (Dynamic Method Dispatch)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[추상 클래스 VS 인터페이스]]></title>
            <link>https://velog.io/@chanhong-dev/%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4-VS-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@chanhong-dev/%EC%B6%94%EC%83%81-%ED%81%B4%EB%9E%98%EC%8A%A4-VS-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Mon, 08 Aug 2022 13:27:06 GMT</pubDate>
            <description><![CDATA[<h2 id="추상-클래스-abstract-class">추상 클래스 (abstract class)</h2>
<h3 id="미완성-설계도">미완성 설계도</h3>
<ul>
<li><code>abstract</code> 키워드를 붙이면 됨.</li>
<li>추상 클래스는 추상 메소드를 0개 이상 가지고 있다는 것을 제외하고 일반 클래스와 다르지 않음.</li>
<li>추상 메소드는 선언부는 있는데 구현부가 없는 메소드
자식 클래스에서 반드시 <strong>오버라이딩</strong>해야만 사용할 수 있는 메소드</li>
<li>추상 메소드를 포함하는 클래스는 반드시 초상 클래스여야 함.</li>
<li><strong>다중 상속이 불가능</strong></li>
<li>상속하는 집한간에는 연관관계가 존재</li>
<li>상속을 위한 클래스이기 때문에 객체(인스턴스)를 생성할 수 없음.</li>
</ul>
<pre><code class="language-java">abstract class 클래스이름 {
    ...
    public abstract void 메서드이름();
}</code></pre>
<ul>
<li>추상 클래스를 상속받는 모든 클래스에서는 이 추상 메소드를 반드시 재정의 해야함.
→ 자식클래스에서 추상클래스의 모든 추상 메소드를 오버라이딩 하고 나서야 비로소 자식클래스의 인스턴스를 생성할 수 있음.</li>
<li>생성자와 필드, 일반 메소드 포함 가능</li>
</ul>
<pre><code class="language-java">abstract class Animal { abstract void cry(); }

class Cat extends Animal { void cry() { System.out.println(&quot;냐옹냐옹!&quot;); } }
class Dog extends Animal { void cry() { System.out.println(&quot;멍멍!&quot;); } }


public class Polymorphism02 {
    public static void main(String[] args) {
        // Animal a = new Animal(); // 추상 클래스는 인스턴스를 생성할 수 없음.

        Cat c = new Cat();
        Dog d = new Dog();

        c.cry();
        d.cry();
    }
}</code></pre>
<h3 id="추상-메소드의-목적">추상 메소드의 목적</h3>
<ul>
<li>추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함.</li>
</ul>
<hr>
<h2 id="인터페이스-interface">인터페이스 (Interface)</h2>
<h3 id="기본-설계도">기본 설계도</h3>
<ul>
<li>자바에서 클래스들이 구현해야하는 동작을 지정하는 용도로 사용되는 추상 자료형</li>
<li><code>interface</code> 키워드를 이용하여 선언</li>
<li><strong>다중 상속</strong>이 가능</li>
<li>상속하는 집한간에는 연관관계가 존재하지 않을 수 있음.</li>
<li>모든 멤버 변수는 <code>public static final</code> 이어야 하며, 이를 생략할 수 있음.</li>
<li>모든 메소드는 <code>public abstract</code> 이어야 하며, 이를 생략할 수 있음.</li>
<li>생략 시 컴파일러가 자동 추가</li>
</ul>
<pre><code class="language-java">// 접근 지정자는 public 만 가능 , class 설계도 이기 때문에 존재 목적이 &quot;공개&quot;
public interface 인터페이스이름 {
    public static final 타입 상수이름 = 값;
    ...
    public abstract 메소드이름(매개변수목록);
    ...
}</code></pre>
<ul>
<li>인터페이스는 오로지 추상 메소드와 상수만을 포함할 수 있음.</li>
<li>직접 인스턴스를 생성할 수 없음.</li>
<li>객체를 생성할 수 없기 때문에, 생성자를 가질 수 없음.</li>
<li>Java7 까지는 추상 메소드로만 선언이 가능 
→ Java8 부터는 <code>디폴트 메소드</code>와 <code>정적 메소드</code> 선언 가능</li>
</ul>
<blockquote>
<p>interface 도 Class, Enum, Annotation 처럼 <code>~.java</code> 파일로 작성되고, 
<code>~.class</code> 파일로 컴파일 된다.</p>
</blockquote>
<h3 id="인터페이스의-구현">인터페이스의 구현</h3>
<pre><code class="language-java">class 클래스이름 extend 상위클래스이름 implements 인터페이스이름 { ... }</code></pre>
<ol>
<li>단일 인터페이스 구현 클래스 </li>
<li>다중 인터페이스 구현 클래스</li>
<li>익명 구현 객체</li>
</ol>
<h3 id="인터페이스의-역할">인터페이스의 역할</h3>
<ul>
<li>객체를 어떻게 구성해야 하는지 정리한 설계도</li>
<li>객체의 교환성(또는 다형성)을 높여줌.</li>
</ul>
<h3 id="인터페이스의-장점">인터페이스의 장점</h3>
<ul>
<li>대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화 가능</li>
<li>클래스의 작성과 인터페이스의 구현을 동시에 진행할 수 있으므로, 개발시간 단축</li>
<li>클래스와 클래스 간의 관계를 인터페이스로 연결하며, 클래스마다 독립적인 프로그래밍 가능</li>
</ul>
<hr>
<h2 id="추상-클래스와-인터페이스의-차이점">추상 클래스와 인터페이스의 차이점</h2>
<h3 id="공통점">공통점</h3>
<ol>
<li>메소드의 선언만 있고, 구현 내용이 없음</li>
<li>객체 ( 인스턴스 ) 생성 불가</li>
<li>상속받은 자식 클래스에서 반드시 추상 메소드를 구현하도록 강제 됨.</li>
</ol>
<h3 id="차이점">차이점</h3>
<ol>
<li><strong>접근자</strong><ol>
<li>인터페이스에서 모든 변수는 <code>public static final</code>, 모든 메소드는 <code>public abstract</code> 임.</li>
<li>추상 클래스에서는 <code>static</code>이나 <code>final</code>이 아닌 필드를 가질 수 있고, <code>public</code>, <code>protected</code>, <code>private</code> 모두 가질 수 있음.</li>
</ol>
</li>
<li><strong>다중 상속 여부</strong><ol>
<li>인터페이스를 구현하는 클래스는 다른 여러개 인터페이스를 함께 구현할 수 있음.</li>
<li>자바에서는 다중 상속을 지원하지 않기 때문에 여러 추상 클래스를 상속할 수 없음.</li>
</ol>
</li>
<li><strong>사용 의도</strong><ol>
<li>추상 클래스는 객체들의 공통점을 찾아 추상화 시켜 놓은 것.
부모 클래스가 가진 기능들을 확장 구현해야할 경우 사용</li>
<li>인터페이스는 클래스와 별도로 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용
공통된 기능</li>
</ol>
</li>
<li><strong>적정한 사용 케이스</strong><ol>
<li>추상 클래스<ol>
<li>관련성 높은 클래스 간에 코드를 공유하고 싶은 경우</li>
<li>추상 클래스를 상속 받을 클래스들이 공통으로 가지는 메소드와 필드가 많은 경우</li>
<li><code>non-static</code>, <code>non-final</code> 필드 선언이 필요한 경우</li>
</ol>
</li>
<li>인터페이스<ol>
<li>서로 관련성 없는 클래스들이 인터페이스를 구현하게 되는 경우</li>
<li>다중 상속을 허용하고 싶은 경우</li>
<li>특정 데이터 타입의 행동을 명시하고 싶은데, 어디서 그 행동이 구현되는지는 신경쓰지 않는 경우</li>
</ol>
</li>
</ol>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images%2Fnew_wisdom%2Fpost%2Faf9d99ef-28f2-483f-a261-161cb979fb4a%2Fimage.png" alt="Untitled"></p>
]]></description>
        </item>
    </channel>
</rss>