자바 인터페이스 와 추상 류 의 차이 에 대한 상세 한 설명
서로 다른 프로 그래 밍 언어 는 인터페이스 와 추상 류 에 대한 정의 방식 에 차이 가 있 을 수 있 지만 차이 가 크 지 않다.본문 은 자바 언어 를 사용한다.
추상 류
다음은 우 리 는 하나의 예 를 통 해 전형 적 인 추상 류 의 사용 장면 을 볼 수 있다.
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 요청 에 대한 감 권 과 흐름 제한 필터 기능 을 실 현 했 습 니 다.다음은 인터페이스의 특성 을 살 펴 보 겠 습 니 다.
종합 적 으로 문법 적 으로 비교 하면 이 두 가 지 는 비교적 큰 차이 가 있다.예 를 들 어 추상 류 에서 속성,방법의 실현 을 정의 할 수 있 지만 인터페이스 에서 속성 을 정의 할 수 없고 방법 도 실현 을 포함 할 수 없다.
문법 적 특성 이 다른 것 을 제외 하고 디자인 의 측면 에서 도 이 두 가 지 는 비교적 큰 차이 가 있다.추상 류 는 본질 적 으로 유형 이 고 특수 한 유형 에 불과 하 다.이런 유형 은 실례 화 되 지 않 고 이불 류 만 계승 할 수 있다.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()방법 을 다시 써 서 자신의 기록 로그 논 리 를 실현 하도록 합 니 다.이런 방식 을 사용 하면 위의 문 제 를 해결 할 수 있 습 니까?일단 생각 을 해 보 세 요.이 사고방식 은 사용 할 수 있 지만 우아 하지 않다.주로 몇 가지 이유 가 있다.
실제로 인 터 페 이 스 는 추상 적 인 응용 보다 더욱 광범 위 하고 중요 한 지식 이다.예 를 들 어 우리 가 자주 언급 하 는'인 터 페 이 스 를 바탕 으로 프로 그래 밍 을 실현 하 는 것 이 아니 라'는 것 은 거의 매일 사용 되 는 것 이 고 코드 의 유연성,확장 성 을 크게 향상 시 킬 수 있 는 디자인 사상 이다.
어떻게 추상 류 와 인 터 페 이 스 를 모 의 합 니까?
앞에서 열거 한 예 에서 우 리 는 자바 의 인 터 페 이 스 를 사용 하여 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.추상 류 와 인터페이스의 응용 장면 은 어떤 것들 이 있 습 니까?
이상 은 자바 인터페이스 와 추상 류 의 차이 에 대한 상세 한 내용 입 니 다.자바 인터페이스 와 추상 류 에 관 한 자 료 는 우리 의 다른 관련 글 에 관심 을 가 져 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.