자바 인터페이스 와 추상 류 의 차이 에 대한 상세 한 설명

무엇이 추상 류 와 인터페이스 입 니까?차이 가 어디 에 있 습 니까?
서로 다른 프로 그래 밍 언어 는 인터페이스 와 추상 류 에 대한 정의 방식 에 차이 가 있 을 수 있 지만 차이 가 크 지 않다.본문 은 자바 언어 를 사용한다.
추상 류
다음은 우 리 는 하나의 예 를 통 해 전형 적 인 추상 류 의 사용 장면 을 볼 수 있다.
Logger 는 로 그 를 기록 하 는 추상 적 인 클래스 입 니 다.FileLogger 와 Message QueueLogger 는 Logger 를 계승 하여 각각 두 가지 서로 다른 로그 기록 방식 을 실현 합 니 다.
파일 에 로 그 를 기록 합 니 다메시지 대기 열 에 로 그 를 기록 합 니 다.
FileLogger 와 Message QueuLogger 두 개의 하위 클래스 는 부모 클래스 Logger 의 name,enabled,minPermitted Level 속성 과 log 방법 을 재 활용 하 였 으 나,두 개의 하위 클래스 가 로 그 를 쓰 는 방식 이 다 르 기 때문에 각각 부모 클래스 의 doLog 방법 을 다시 썼 다.
부계

import java.util.logging.Level;

/**
 *     
 * @author yanliang
 * @date 9/27/2020 5:59 PM
 */
public abstract class Logger {
    private String name;
    private boolean enabled;
    private Level minPermittedLevel;

    public Logger(String name, boolean enabled, Level minPermittedLevel) {
        this.name = name;
        this.enabled = enabled;
        this.minPermittedLevel = minPermittedLevel;
    }

    public void log(Level level, String message) {
        boolean loggable = enabled && (minPermittedLevel.intValue() <= level.intValue());
        if(!loggable) return;
        doLog(level, message);
    }

    protected abstract void doLog(Level level, String message);
}
FileLogger

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.logging.Level;

/**
 *    Logger   :        
 * @author yanliang
 * @date 9/28/2020 4:44 PM
 */
public class FileLogger extends Logger {

    private Writer fileWriter;

    public FileLogger(String name, boolean enabled, Level minPermittedLevel, String filePath) throws IOException {
        super(name, enabled, minPermittedLevel);
        this.fileWriter = new FileWriter(filePath);
    }

    @Override
    protected void doLog(Level level, String message) {
        //    level   message,       
        fileWriter.write(...);
    }
}
MessageQueuLogger

import java.util.logging.Level;

/**
 *    Logger   :          
 * @author yanliang
 * @date 9/28/2020 6:39 PM
 */
public class MessageQueueLogger extends Logger {

    private MessageQueueClient messageQueueClient;

    public MessageQueueLogger(String name, boolean enabled, Level minPermittedLevel, MessageQueueClient messageQueueClient) {
        super(name, enabled, minPermittedLevel);
        this.messageQueueClient = messageQueueClient;
    }

    @Override
    protected void doLog(Level level, String message) {
        //    level   message,        
        messageQueueClient.send(...)
    }
}
위의 예 를 통 해 우 리 는 추상 류 가 어떤 특성 을 가지 고 있 는 지 살 펴 보 자.
4.567917.추상 류 는 예화 되 지 않 고 계승 할 수 밖 에 없다.(new 추상 클래스,컴 파일 오류 보고)4.567917.추상 류 는 속성 과 방법 을 포함 할 수 있다.방법 은 실현 도 포함 할 수 있 고 실현 도 포함 하지 않 을 수 있다.실현 방법 을 포함 하지 않 는 것 을 추상 적 인 방법 이 라 고 한다.
4.567917.자 류 는 추상 류 를 계승 하고 추상 류 중의 모든 추상 적 인 방법 을 실현 해 야 한다.
인터페이스
마찬가지 로 다음 에 우 리 는 하나의 예 를 통 해 인터페이스의 사용 장면 을 살 펴 보 자.

/**
 *      
 * @author yanliang
 * @date 9/28/2020 6:46 PM
 */
public interface Filter {
    void doFilter(RpcRequest req) throws RpcException;
}

/**
 *      :     
 * @author yanliang
 * @date 9/28/2020 6:48 PM
 */
public class AuthencationFilter implements Filter {

    @Override
    public void doFilter(RpcRequest req) throws RpcException {
        //     
    }
}

/**
 *      :     
 * @author yanliang
 * @date 9/28/2020 6:48 PM
 */
public class RateLimitFilter implements Filter{

    @Override
    public void doFilter(RpcRequest req) throws RpcException {
        //     
    }
}

/**
 *      demo
 * @author yanliang
 * @date 9/28/2020 6:48 PM
 */
public class Application {
    //      
    private List<Filter> filters = new ArrayList<>();
    filters.add(new AuthencationFilter());
    filters.add(new RateLimitFilter());

    public void handleRpcRequest(RpcRequest req) {
        try {
            for (Filter filter : filters) {
                filter.doFilter(req);
            }
        } catch (RpcException e) {
            //       
        }
        // ...
    }
}
위의 사례 는 전형 적 인 인터페이스 사용 장면 이다.자바 의 interface 키 워드 를 통 해 Filter 인 터 페 이 스 를 정 의 했 습 니 다.AuthencationFilter 와 RetaLimitFilter 는 인터페이스의 두 가지 실현 클래스 로 각각 Rpc 요청 에 대한 감 권 과 흐름 제한 필터 기능 을 실 현 했 습 니 다.
다음은 인터페이스의 특성 을 살 펴 보 겠 습 니 다.
  • 인 터 페 이 스 는 속성(즉 구성원 변수)을 포함 할 수 없습니다
  • 인 터 페 이 스 는 생명 방법 만 있 을 수 있 고 방법 은 코드 실현 을 포함 할 수 없다
  • 4.567917.클래스 가 인 터 페 이 스 를 실현 할 때 인터페이스 에 있 는 생명의 모든 방법 을 실현 해 야 한다.
    종합 적 으로 문법 적 으로 비교 하면 이 두 가 지 는 비교적 큰 차이 가 있다.예 를 들 어 추상 류 에서 속성,방법의 실현 을 정의 할 수 있 지만 인터페이스 에서 속성 을 정의 할 수 없고 방법 도 실현 을 포함 할 수 없다.
    문법 적 특성 이 다른 것 을 제외 하고 디자인 의 측면 에서 도 이 두 가 지 는 비교적 큰 차이 가 있다.추상 류 는 본질 적 으로 유형 이 고 특수 한 유형 에 불과 하 다.이런 유형 은 실례 화 되 지 않 고 이불 류 만 계승 할 수 있다.is-a 에 속 하 는 관계.인 터 페 이 스 는 has-a 의 관계 로 어떤 기능 을 가지 고 있 음 을 나타 낸다.인터페이스 에 대해 더 이미지 있 는 이름 이 있 습 니 다:프로 토 콜(contract)
    추상 류 와 인 터 페 이 스 는 어떤 문 제 를 해결 합 니까?
    저희 가 먼저 고민 을 해 보도 록 하 겠 습 니 다.
    추상 류 의 존재 의 미 는 코드 재 활용 문 제 를 해결 하기 위 한 것 이다.
    그렇다면 계승 자체 가 코드 재 활용 의 목적 을 달성 할 수 있 고 계승 도 반드시 추상 류 를 요구 하 는 것 은 아니다.우 리 는 추상 류 를 적용 하지 않 고 계승 과 재 활용 도 가능 할 것 같다.이런 측면 에서 볼 때 우 리 는 추상 적 인 문법 이 필요 하지 않 은 것 같다.그 추상 류 는 코드 재 활용 문 제 를 해결 하 는 것 외 에 또 다른 존재 하 는 의미 가 있 습 니까?
    여 기 는 일단 생각 을 해 보 셔 도 될 것 같 아 요.
    우 리 는 위의 Logger 의 예 를 빌려 먼저 위의 사례 를 개조 하 는 것 이 좋 겠 다.개조 후의 실현 에서 Logger 는 더 이상 추상 적 인 클래스 가 아니 라 일반적인 부모 클래스 일 뿐 Logger 중의 두 가지 방법 을 삭제 하고 isLoggable()방법 을 추가 했다.FileLogger 와 Message QueueLogger 는 Logger 부모 클래스 를 계승 하여 코드 재 활용 의 목적 을 달성 하 였 습 니 다.구체 적 인 코드 는 다음 과 같다.
    
    /**
     *   :    ,      
     * @author yanliang
     * @date 9/27/2020 5:59 PM
     */
    public class Logger {
        private String name;
        private boolean enabled;
        private Level minPermittedLevel;
    
        public Logger(String name, boolean enabled, Level minPermittedLevel) {
            this.name = name;
            this.enabled = enabled;
            this.minPermittedLevel = minPermittedLevel;
        }
    
        public boolean isLoggable(Level level) {
            return enabled && (minPermittedLevel.intValue() <= level.intValue());
        }
    
    }
    
    /**
     *    Logger   :        
     * @author yanliang
     * @date 9/28/2020 4:44 PM
     */
    public class FileLogger extends Logger {
    
        private Writer fileWriter;
    
        public FileLogger(String name, boolean enabled, Level minPermittedLevel, String filePath) throws IOException {
            super(name, enabled, minPermittedLevel);
            this.fileWriter = new FileWriter(filePath);
        }
    
        protected void log(Level level, String message) {
            if (!isLoggable(level)) return ;
            //    level   message,       
            fileWriter.write(...);
        }
    }
    
    package com.yanliang.note.java.abstract_demo;
    
    import java.util.logging.Level;
    
    /**
     *    Logger   :          
     * @author yanliang
     * @date 9/28/2020 6:39 PM
     */
    public class MessageQueueLogger extends Logger {
    
        private MessageQueueClient messageQueueClient;
    
        public MessageQueueLogger(String name, boolean enabled, Level minPermittedLevel, MessageQueueClient messageQueueClient) {
            super(name, enabled, minPermittedLevel);
            this.messageQueueClient = messageQueueClient;
        }
    
        protected void log(Level level, String message) {
            if (!isLoggable(level)) return ;
            //    level   message,        
            messageQueueClient.send(...)
        }
    }
    이상 은 코드 재 활용 의 목적 을 달성 하 였 으 나 다 중 특성 을 사용 할 수 없습니다.
    Logger 에 log()방법 이 정의 되 어 있 지 않 기 때문에 아래 와 같이 코드 를 작성 하면 컴 파일 오류 가 발생 합 니 다.
    
    Logger logger = new FileLogger("access-log", true, Level.WARN, "/user/log");
    logger.log(Level.ERROR, "This is a test log message.");
    만약 에 우리 가 부모 클래스 에서 빈 log()방법 을 정의 하면 하위 클래스 가 부모 클래스 의 log()방법 을 다시 써 서 자신의 기록 로그 논 리 를 실현 하도록 합 니 다.이런 방식 을 사용 하면 위의 문 제 를 해결 할 수 있 습 니까?일단 생각 을 해 보 세 요.
    이 사고방식 은 사용 할 수 있 지만 우아 하지 않다.주로 몇 가지 이유 가 있다.
  • Logger 에서 빈 방법 을 정의 하면 코드 의 가 독성 에 영향 을 줄 수 있 습 니 다.Logger 뒤의 디자인 사상 에 익숙 하지 않 고 코드 주석 도 없 으 면 Logger 코드 를 읽 을 때 의문 을 느낀다(왜 여기에 빈 log()방법 이 존재 하 는 지)
  • 4.567917.새로운 하위 클래스 를 만 들 때 Logger 부모 클래스 를 계승 할 때 log 방법 을 다시 실현 하 는 것 을 잊 을 수도 있 습 니 다.이전 에는 추상 적 인 디자인 사상 을 바탕 으로 컴 파일 러 는 하위 클래스 에 부모 클래스 의 log 방법 을 다시 쓰 도록 강요 할 것 이다.그렇지 않 으 면 컴 파일 오 류 를 보고 할 것 이다
  • Logger 는 실례 화 될 수 있 는데 이것 은 이 빈 log 방법 이 호출 될 수 있다 는 것 을 의미한다.이것 은 오 용 될 위험 을 증가 시 켰 다.물론 이 문 제 는 개인 적 인 구조 함 수 를 설정 하 는 방식 으로 해결 할 수 있 지만 추상 적 이 고 우아 하지 않다.
  • 추상 류 는 코드 재 활용 을 위 한 것 이 고 인 터 페 이 스 는 디 결합 에 중심 을 둔다.인 터 페 이 스 는 행위 에 대한 추상 적 인 것 으로 하나의 협의 나 계약(유사 API 인터페이스)에 해당 한다.호출 자 는 추상 적 인 인터페이스 에 만 관심 을 가 져 야 하고 구체 적 인 실현 을 알 필요 가 없 으 며 구체 적 인 실현 코드 는 호출 자 에 게 투명 하 다.인 터 페 이 스 는 약속 과 실현 의 분 리 를 실현 하여 코드 간 의 결합 을 낮 추고 코드 의 확장 성 을 높 일 수 있다.
    실제로 인 터 페 이 스 는 추상 적 인 응용 보다 더욱 광범 위 하고 중요 한 지식 이다.예 를 들 어 우리 가 자주 언급 하 는'인 터 페 이 스 를 바탕 으로 프로 그래 밍 을 실현 하 는 것 이 아니 라'는 것 은 거의 매일 사용 되 는 것 이 고 코드 의 유연성,확장 성 을 크게 향상 시 킬 수 있 는 디자인 사상 이다.
    어떻게 추상 류 와 인 터 페 이 스 를 모 의 합 니까?
    앞에서 열거 한 예 에서 우 리 는 자바 의 인 터 페 이 스 를 사용 하여 Filter 필 터 를 실현 했다.그러나 C++에서 추상 류 만 제공 하고 인 터 페 이 스 를 제공 하지 않 았 다.그러면 코드 의 측면 에서 볼 때 Filter 의 디자인 방향 을 실현 할 수 없 지 않 을 까?일단 생각 을 해 보 세 요.🤔 ~
    우 리 는 먼저 인터페이스의 정 의 를 내 렸 다.인터페이스 에 구성원 변수 가 없고 방법 만 설명 할 뿐 실현 할 방법 이 없고 인 터 페 이 스 를 실현 하 는 클래스 는 반드시 인터페이스 에 있 는 모든 방법 을 실현 해 야 한다.주로 상기 몇 가 지 를 만족 시 키 고 디자인 의 측면 에서 볼 때 우 리 는 그 를 인터페이스 라 고 부 를 수 있다.
    실제로 인터페이스의 이러한 특성 을 만족 시 키 는 것 은 어렵 지 않다.다음은 실현 을 살 펴 보 자.
    
    class Strategy {
      public: 
        -Strategy();
        virtual void algorithm()=0;
      protected:
        Strategy();
    }
    추상 류 Strategy 는 어떠한 속성 도 정의 하지 않 았 고 모든 방법 이 virtual 형식(자바 의 abstract 키워드 와 같다)이 라 고 밝 혔 다.그러면 모든 방법 은 코드 가 실현 되 지 못 하고 이 추상 류 를 계승 한 모든 하위 클래스 는 이런 방법 을 실현 해 야 한다.문법 적 특성 상 이 추상 류 는 하나의 인터페이스 에 해당 한다.
    처 리 는 추상 류 로 인 터 페 이 스 를 모 의 하 는 것 외 에 우 리 는 일반 류 로 인 터 페 이 스 를 모 의 할 수 있다.구체 적 인 자바 실현 은 다음 과 같다.
    
    public class MockInterface {
      protected MockInteface();
      public void funcA() {
        throw new MethodUnSupportedException();
      }
    }
    우 리 는 클래스 의 방법 이 인터페이스의 정의 에 부합 되 지 않 는 실현 을 포함해 야 한 다 는 것 을 안다.그러나 우 리 는 클래스 의 방법 으로 MethodUnSupported Exception 이상 을 던 져 실현 되 지 않 은 인 터 페 이 스 를 모 의 하고 하위 클래스 에 게 이 부 류 를 계승 하도록 강요 할 때 부모 클래스 를 주동 적 으로 실현 하 는 방법 을 사용 할 수 있 습 니 다.그렇지 않 으 면 운행 할 때 이상 을 던 질 수 있 습 니 다.
    그러면 어떻게 이런 종류의 실례 화 를 피 할 수 있 습 니까?실제로 매우 간단 합 니 다.우 리 는 이러한 구조 함 수 를 proctected 접근 권한 으로 만 설명 하면 됩 니 다.
    어떻게 추상 을 사용 해 야 할 지 아니면 인 터 페 이 스 를 사용 해 야 할 지 결정 합 니까?
    위의 설명 은 이론 에 치 우 칠 수 있 으 니,지금 우 리 는 실제 프로젝트 개발 의 측면 에서 볼 것 이다.코드 디자인/프로 그래 밍 을 할 때 언제 인 터 페 이 스 를 사용 해 야 합 니까?언제 추상 류 를 써 야 합 니까?
    사실 판단 의 기준 은 간단 하 다.만약 에 우리 가 is-a 관 계 를 필요 로 하고 코드 재 활용 문 제 를 해결 하기 위해 추상 적 인 유형 을 사용한다.만약 에 우리 가 필요 한 것 이 has-a 관계 이 고 코드 재 활용 문 제 를 해결 하기 위해 서 라면 우 리 는 인 터 페 이 스 를 사용 할 것 이다.
    유형의 계승 차원 에서 볼 때 추상 류 는 아래 에서 위로 의 디자인 사고 로 먼저 하위 류 의 코드 를 재 활용 한 다음 에 상층 의 아버지 류(즉 추상 류)로 추상 화 된다.한편,인 터 페 이 스 는 반대로 위 에서 아래로 의 디자인 사고 이다.우 리 는 프로 그래 밍 을 할 때 보통 인 터 페 이 스 를 먼저 설계 한 다음 에 구체 적 인 실현 을 생각한다.
    자,당신 은 위의 내용 을 파악 하 였 습 니까?너 는 몇 가지 차원 을 통 해 자체 검 사 를 돌 이 켜 볼 수 있다.
    추상 류 와 인터페이스의 문법 적 특성
    추상 류 와 인터페이스 에 존재 하 는 의미4.567917.추상 류 와 인터페이스의 응용 장면 은 어떤 것들 이 있 습 니까?
    이상 은 자바 인터페이스 와 추상 류 의 차이 에 대한 상세 한 내용 입 니 다.자바 인터페이스 와 추상 류 에 관 한 자 료 는 우리 의 다른 관련 글 에 관심 을 가 져 주 십시오!

    좋은 웹페이지 즐겨찾기