인터뷰 중 하나에서 인터페이스 와 추상 클래스 의 차이점을 설명하라는 요청을 받았습니다 .
내 대답은 다음과 같습니다.
Java 인터페이스의 메소드는 내재적으로 추상적이며 구현할 수 없습니다. Java 추상 클래스에는 기본 동작을 구현하는 인스턴스 메소드가있을 수 있습니다.
Java 인터페이스에서 선언 된 변수는 기본적으로 final입니다. 추상 클래스에는 비 최종 변수가 포함될 수 있습니다.
Java 인터페이스의 멤버는 기본적으로 공용입니다. Java 추상 클래스는 개인, 보호 등의 일반적인 클래스 멤버를 가질 수 있습니다.
Java 인터페이스는 키워드 “implements”를 사용하여 구현해야합니다. 키워드“extends”를 사용하여 Java 추상 클래스를 확장해야합니다.
인터페이스는 다른 Java 인터페이스 만 확장 할 수 있으며 추상 클래스는 다른 Java 클래스를 확장하고 여러 Java 인터페이스를 구현할 수 있습니다.
Java 클래스는 여러 인터페이스를 구현할 수 있지만 하나의 추상 클래스 만 확장 할 수 있습니다.
그러나 면접관은 만족하지 않았으며,이 설명은 ” 서적 지식 “을 대표한다고 말했다 .
그는 실용적인 예제를 사용하여 인터페이스를 통해 추상 클래스를 선택할 때를 설명하는보다 실용적인 응답을 요청했습니다 .
내가 어디로 잘못 갔니?
답변
먼저 예를 들어 보겠습니다.
public interface LoginAuth{
public String encryptPassword(String pass);
public void checkDBforUser();
}
응용 프로그램에 3 개의 데이터베이스가 있다고 가정하십시오. 그런 다음 해당 데이터베이스에 대한 모든 구현마다 위의 두 가지 방법을 정의해야합니다.
public class DBMySQL implements LoginAuth{
// Needs to implement both methods
}
public class DBOracle implements LoginAuth{
// Needs to implement both methods
}
public class DBAbc implements LoginAuth{
// Needs to implement both methods
}
그러나 encryptPassword()
데이터베이스에 의존하지 않고 각 클래스마다 동일한 경우 어떻게해야합니까? 그렇다면 위의 방법은 좋지 않습니다.
대신이 접근법을 고려하십시오.
public abstract class LoginAuth{
public String encryptPassword(String pass){
// Implement the same default behavior here
// that is shared by all subclasses.
}
// Each subclass needs to provide their own implementation of this only:
public abstract void checkDBforUser();
}
이제 각 자식 클래스에서 데이터베이스에 의존하는 메서드 하나만 구현하면됩니다.
답변
이 세상에서 완벽한 것은 없습니다. 그들은 실제적인 접근 방식을 기대했을 수도 있습니다.
그러나 설명 후에 약간 다른 접근 방식 으로이 줄을 추가 할 수 있습니다.
-
인터페이스는 소프트웨어 개발의 여러 팀에서 공통으로 이해하는 문서로 작동하는 규칙 (규칙을 무시하거나 피할 수없는 구현을 제공해야하기 때문에 적용되는 규칙)입니다.
-
인터페이스는 수행해야 할 작업에 대한 아이디어를 제공하지만 수행 방법은 제공하지 않습니다. 따라서 구현은 주어진 규칙에 따라 개발자에게 전적으로 달려 있습니다 (메소드의 서명이 주어진다는 것을 의미합니다).
-
추상 클래스에는 추상 선언, 구체적 구현 또는 둘 다가 포함될 수 있습니다.
-
추상 선언은 준수해야 할 규칙과 같으며 구체적인 구현은 지침과 같습니다 (그대로 그대로 사용하거나 구현을 재정의하고이를 통해 무시할 수 있음).
-
또한 동일한 서명을 가진 메소드가 다른 컨텍스트에서 동작을 변경할 수있는 것은 다른 컨텍스트에서 적절하게 구현하기위한 규칙으로 인터페이스 선언으로 제공됩니다.
편집 : Java 8을 사용하면 인터페이스에서 기본 및 정적 메소드를 쉽게 정의 할 수 있습니다.
public interface SomeInterfaceOne {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceOne defaultMethod::"+inputString);
}
}
클래스가 SomeInterface를 구현할 때 인터페이스의 기본 메소드에 대한 구현을 반드시 제공 할 필요는 없습니다.
다음 방법으로 다른 인터페이스가있는 경우 :
public interface SomeInterfaceTwo {
void usualAbstractMethod(String inputString);
default void defaultMethod(String inputString){
System.out.println("Inside SomeInterfaceTwo defaultMethod::"+inputString);
}
}
Java는 컴파일러가 사용할 수퍼 클래스 메소드를 결정할 수없는 “다이아몬드 문제” 가 발생하므로 여러 클래스를 확장 할 수 없습니다. 기본 방법을 사용하면 인터페이스에서도 다이아몬드 문제가 발생합니다. 클래스가 둘 다 구현하는 경우
SomeInterfaceOne and SomeInterfaceTwo
일반적인 기본 방법을 구현하지 않으면 컴파일러가 선택할 방법을 결정할 수 없습니다. 이 문제를 피하려면 Java 8에서는 다른 인터페이스의 공통 기본 메소드를 구현해야합니다. 위의 인터페이스를 모두 구현하는 클래스가있는 경우 defaultMethod () 메서드에 대한 구현을 제공해야합니다. 그렇지 않으면 컴파일러에서 컴파일 시간 오류가 발생합니다.
답변
실제 사용 및 구현의 차이점을 요약했지만 의미의 차이점에 대해서는 언급하지 않았습니다.
인터페이스는 구현 클래스가있을 것이다 동작에 대한 설명입니다. 구현 클래스는 이러한 메소드를 사용할 수 있도록 보장합니다. 그것은 기본적으로 수업이해야 할 계약 또는 약속입니다.
추상 클래스는 반복적으로 생성 할 필요가 없습니다 주 행동이 다른 서브 클래스의 기초입니다. 서브 클래스는 동작을 완료하고 미리 정의 된 동작을 재정의하는 옵션이 있어야합니다 ( final
또는로 정의되지 않은 경우 private
).
java.util
패키지 에서 이미 인터페이스를 구현하는 List
것과 같은 인터페이스 와 추상 클래스 를 포함 하는 좋은 예를 찾을 수 AbstractList
있습니다. 공식 문서는 설명 AbstractList
은 다음과 같습니다 :
이 클래스는 “랜덤 액세스”데이터 저장소 (예 : 배열)로 지원되는이 인터페이스를 구현하는 데 필요한 노력을 최소화하기 위해 List 인터페이스의 골격 구현을 제공합니다.
답변
인터페이스는 싱글 톤 변수 (공개 정적 최종) 및 공용 추상 메소드로 구성됩니다. 우리는 일반적으로 해야 할 일을 알고 있지만 어떻게 해야할지 모르는 경우 실시간으로 인터페이스를 사용하는 것을 선호 합니다 .
이 개념은 예를 통해 더 잘 이해할 수 있습니다.
지불 클래스를 고려하십시오. 지불은 PayPal, 신용 카드 등과 같은 여러 가지 방법으로 이루어질 수 있습니다. 따라서 일반적으로 makePayment()
Method 를 포함하는 인터페이스로 Payment를 사용하고 CreditCard 및 PayPal은 두 가지 구현 클래스입니다.
public interface Payment
{
void makePayment();//by default it is a abstract method
}
public class PayPal implements Payment
{
public void makePayment()
{
//some logic for PayPal payment
//e.g. Paypal uses username and password for payment
}
}
public class CreditCard implements Payment
{
public void makePayment()
{
//some logic for CreditCard payment
//e.g. CreditCard uses card number, date of expiry etc...
}
}
위의 예에서 CreditCard와 PayPal은 두 가지 구현 클래스 / 전략입니다. 인터페이스는 또한 추상 클래스로는 달성 할 수없는 Java의 다중 상속 개념을 허용합니다.
우리는 무엇을해야하는지, 수행 방법을 알고있는 다른 기능이있을 때 추상 클래스를 선택합니다 .
다음 예제를 고려하십시오.
public abstract class Burger
{
public void packing()
{
//some logic for packing a burger
}
public abstract void price(); //price is different for different categories of burgers
}
public class VegBerger extends Burger
{
public void price()
{
//set price for a veg burger.
}
}
public class NonVegBerger extends Burger
{
public void price()
{
//set price for a non-veg burger.
}
}
미래에 주어진 추상 클래스에 메소드 (콘크리트 / 추상)를 추가하면 구현 클래스에서 코드를 변경할 필요가 없습니다. 그러나 나중에 인터페이스에 메소드를 추가하는 경우 해당 인터페이스를 구현 한 모든 클래스에 구현을 추가해야합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다.
다른 차이점이 있지만 면담자가 예상했던 것과 다른 주요 차이점이 있습니다. 잘만되면 이것이 도움이되었다.
답변
Abstact 클래스와 인터페이스의 차이점
- Java 8의 추상 클래스와 인터페이스
- 개념적 차이 :
Java 8의 인터페이스 기본 메소드
- 기본 방법은 무엇입니까?
- 기본 메소드를 사용하여 ForEach 메소드 컴파일 오류가 해결되었습니다.
- 기본 방법 및 다중 상속 모호성 문제
- Java 인터페이스 기본 메소드에 대한 중요한 사항 :
자바 인터페이스 정적 메소드
- Java 인터페이스 정적 메소드, 코드 예제, 정적 메소드 및 기본 메소드
- Java 인터페이스 정적 메소드에 대한 중요한 사항 :
자바 기능 인터페이스
Java 8의 추상 클래스와 인터페이스
Java 8 인터페이스 변경에는 인터페이스의 정적 메소드 및 기본 메소드가 포함됩니다. Java 8 이전에는 인터페이스에 메소드 선언 만있을 수있었습니다. 그러나 Java 8부터 인터페이스에 기본 메소드와 정적 메소드를 가질 수 있습니다.
기본 메소드를 도입 한 후 인터페이스와 추상 클래스가 동일한 것 같습니다. 그러나 Java 8에서는 여전히 다른 개념입니다.
추상 클래스는 생성자를 정의 할 수 있습니다. 그것들은 더 구조적이고 그들과 관련된 상태를 가질 수 있습니다. 대조적으로, 기본 메소드는 특정 구현 상태를 참조하지 않고 다른 인터페이스 메소드를 호출하는 측면에서만 구현 될 수 있습니다. 따라서 서로 다른 목적으로 사용하고 두 가지 중에서 선택하는 것은 시나리오 상황에 따라 다릅니다.
개념적 차이 :
추상 클래스는 인터페이스의 골격 (즉, 부분) 구현에 유효하지만 일치하는 인터페이스가 없으면 존재하지 않아야합니다.
따라서 추상 클래스가 효과적으로 보이지 않는 인터페이스의 골격 구현으로 축소되면 기본 메소드도 이것을 제거 할 수 있습니까? 결정적으로 : 아니요! 인터페이스를 구현하려면 거의 항상 기본 메소드에없는 클래스 작성 도구의 일부 또는 전부가 필요합니다. 그리고 어떤 인터페이스가 그렇지 않으면 분명히 특별한 경우이며, 당신을 타락으로 이끌지 않아야합니다.
Java 8의 인터페이스 기본 메소드
Java 8에는“ 기본 메소드 ”또는 (수 비기 메소드) 새로운 기능이 도입되어 개발자가 이러한 인터페이스의 기존 구현을 중단하지 않고도 인터페이스에 새로운 메소드를 추가 할 수 있습니다. 구체적인 클래스가 해당 메소드에 대한 구현을 제공하지 못하는 상황에서 기본값으로 사용할 인터페이스 정의 구현을 허용하는 유연성을 제공합니다.
작동 방식을 이해하기 위해 작은 예를 고려하십시오.
public interface OldInterface {
public void existingMethod();
default public void newDefaultMethod() {
System.out.println("New default method"
+ " is added in interface");
}
}
다음 클래스는 Java JDK 8에서 성공적으로 컴파일됩니다.
public class OldInterfaceImpl implements OldInterface {
public void existingMethod() {
// existing implementation is here…
}
}
OldInterfaceImpl 인스턴스를 작성하는 경우 :
OldInterfaceImpl obj = new OldInterfaceImpl ();
// print “New default method add in interface”
obj.newDefaultMethod();
기본 방법 :
기본 메소드는 최종적이지 않으며 동기화 할 수 없으며 오브젝트의 메소드를 대체 할 수 없습니다. 그것들은 항상 공개적이며 짧고 재사용 가능한 방법을 작성하는 능력을 심각하게 제한합니다.
기본 메소드는 구현을 포함하므로 클래스 구현에 영향을 미치지 않고 인터페이스에 제공 할 수 있습니다. 구현으로 정의 된 인터페이스의 각 추가 된 메소드는 구현 클래스에 영향을 미치지 않습니다. 구현 클래스는 인터페이스에서 제공하는 기본 구현을 대체 할 수 있습니다.
기본 방법을 사용하면 이러한 인터페이스의 이전 구현을 중단하지 않고 기존 인터페이스에 새로운 기능을 추가 할 수 있습니다.
기본 메소드가 포함 된 인터페이스를 확장하면 다음을 수행 할 수 있습니다.
- 기본 방법을 재정의하지 않고 기본 방법을 상속합니다.
- 서브 클래스에서 재정의하는 다른 방법과 유사한 기본 방법을 재정의합니다.
- 기본 메소드를 abstract로 다시 선언하여 서브 클래스가이를 대체하도록합니다.
기본 메소드를 사용하여 ForEach 메소드 컴파일 오류가 해결되었습니다.
Java 8의 경우 JDK 콜렉션이 확장되었으며 forEach 메소드가 전체 콜렉션에 추가되었습니다 (람다와 함께 작동 함). 일반적인 방법으로 코드는 다음과 같습니다.
public interface Iterable<T> {
public void forEach(Consumer<? super T> consumer);
}
따라서 결과적으로 컴파일 오류가있는 각 구현 클래스가 있으므로 기존 구현을 변경하지 않도록 필수 구현으로 기본 메소드를 추가했습니다.
기본 메소드를 사용한 반복 인터페이스는 다음과 같습니다.
public interface Iterable<T> {
public default void forEach(Consumer
<? super T> consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
구현 클래스를 손상시키지 않고 JDK 인터페이스 에 스트림 을 추가하는 데 동일한 메커니즘이 사용되었습니다 .
기본 방법 및 다중 상속 모호성 문제
java 클래스는 여러 인터페이스를 구현할 수 있고 각 인터페이스는 동일한 메소드 서명으로 기본 메소드를 정의 할 수 있으므로 상속 된 메소드가 서로 충돌 할 수 있습니다.
아래 예를 고려하십시오.
public interface InterfaceA {
default void defaultMethod(){
System.out.println("Interface A default method");
}
}
public interface InterfaceB {
default void defaultMethod(){
System.out.println("Interface B default method");
}
}
public class Impl implements InterfaceA, InterfaceB {
}
위의 코드는 다음 오류로 컴파일되지 않습니다.
java : Impl 클래스는 InterfaceA 및 InterfaceB 유형에서 defaultMethod ()에 대해 관련되지 않은 기본값을 상속합니다.
이 클래스를 수정하려면 기본 메소드 구현을 제공해야합니다.
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
}
}
또한 자체 구현이 아닌 수퍼 인터페이스에서 제공하는 기본 구현을 호출하려는 경우 다음과 같이 수행 할 수 있습니다.
public class Impl implements InterfaceA, InterfaceB {
public void defaultMethod(){
// existing code here..
InterfaceA.super.defaultMethod();
}
}
우리는 새로운 방법의 일부로 기본 구현 또는 둘 다를 선택할 수 있습니다.
Java 인터페이스 기본 메소드에 대한 중요한 사항 :
- Java 인터페이스 기본 메소드는 구현 클래스를 중단 할 염려없이 인터페이스를 확장하는 데 도움이됩니다.
- Java 인터페이스 기본 메소드는 인터페이스와 추상 클래스의 차이점을 보완합니다.
- Java 8 인터페이스 기본 메소드는 모든 Collections 클래스 메소드가 인터페이스 자체에서 제공 될 수있는 것과 같은 유틸리티 클래스를 피하는 데 도움이됩니다.
- Java 인터페이스 기본 메소드는 기본 구현 클래스를 제거하는 데 도움이되고 기본 구현을 제공 할 수 있으며 구현 클래스는 대체 할 클래스를 선택할 수 있습니다.
- 인터페이스에 기본 메소드를 도입 한 주요 이유 중 하나는 람다 표현식을 지원하도록 Java 8에서 Collections API를 향상시키는 것입니다.
- 계층 구조의 클래스에 서명이 동일한 메소드가있는 경우 기본 메소드는 관련이 없습니다. 기본 메소드는 java.lang.Object의 메소드를 대체 할 수 없습니다. 추론은 매우 간단합니다. Object는 모든 Java 클래스의 기본 클래스이기 때문입니다. 따라서 인터페이스에 기본 메소드로 정의 된 Object 클래스 메소드가 있더라도 Object 클래스 메소드가 항상 사용되므로 쓸모가 없습니다. 그렇기 때문에 혼동을 피하기 위해 Object 클래스 메서드를 재정의하는 기본 메서드를 가질 수 없습니다.
- Java 인터페이스 기본 메소드는 Defender 메소드 또는 가상 확장 메소드라고도합니다.
리소스 링크 :
자바 인터페이스 정적 메소드
Java 인터페이스 정적 메소드, 코드 예제, 정적 메소드 및 기본 메소드
Java 인터페이스 정적 메소드는 구현 클래스에서이를 대체 할 수 없다는 점을 제외하고 기본 메소드와 유사합니다. 이 기능은 구현 클래스에서 구현이 잘못되었을 때 원하지 않는 결과를 피하는 데 도움이됩니다. 간단한 예를 통해이를 살펴 보겠습니다.
public interface MyData {
default void print(String str) {
if (!isNull(str))
System.out.println("MyData Print::" + str);
}
static boolean isNull(String str) {
System.out.println("Interface Null Check");
return str == null ? true : "".equals(str) ? true : false;
}
}
이제 구현이 좋지 않은 isNull () 메소드가있는 구현 클래스를 보자.
public class MyDataImpl implements MyData {
public boolean isNull(String str) {
System.out.println("Impl Null Check");
return str == null ? true : false;
}
public static void main(String args[]){
MyDataImpl obj = new MyDataImpl();
obj.print("");
obj.isNull("abc");
}
}
isNull (String str)은 간단한 클래스 메서드이며 인터페이스 메서드를 재정의하지 않습니다. 예를 들어, @Nride () 메소드에 @Override 어노테이션을 추가하면 컴파일러 오류가 발생합니다.
이제 우리는 응용 프로그램을 실행할 때 다음과 같은 결과를 얻습니다.
인터페이스 널 점검
Impl 널 점검
인터페이스 메소드를 정적에서 기본값으로 만들면 다음과 같은 출력이 나타납니다.
Impl 널 점검
MyData 인쇄 ::
Impl 널 점검
Java 인터페이스 정적 메소드는 인터페이스 메소드에만 표시됩니다. MyDataImpl 클래스에서 isNull () 메소드를 제거하면 MyDataImpl 오브젝트에이 메소드를 사용할 수 없습니다. 그러나 다른 정적 메소드와 마찬가지로 클래스 이름을 사용하여 인터페이스 정적 메소드를 사용할 수 있습니다. 예를 들어 유효한 진술은 다음과 같습니다.
boolean result = MyData.isNull("abc");
Java 인터페이스 정적 메소드에 대한 중요한 사항 :
- Java 인터페이스 정적 메소드는 인터페이스의 일부이므로 구현 클래스 객체에 사용할 수 없습니다.
- Java 인터페이스 정적 메소드는 유틸리티 메소드 (예 : 널 검사, 콜렉션 정렬 등)를 제공하는 데 유용합니다.
- Java 인터페이스 정적 메소드는 구현 클래스가이를 대체하지 못하도록하여 보안을 제공하는 데 도움이됩니다.
- Object 클래스 메소드에 대한 인터페이스 정적 메소드를 정의 할 수 없습니다.“이 정적 메소드는 Object에서 인스턴스 메소드를 숨길 수 없습니다”라는 컴파일러 오류가 발생합니다. Object는 모든 클래스의 기본 클래스이므로 동일한 서명을 가진 하나의 클래스 레벨 정적 메소드와 다른 인스턴스 메소드를 가질 수 없으므로 java에서는 허용되지 않기 때문입니다.
- java 인터페이스 정적 메소드를 사용하여 Collections와 같은 유틸리티 클래스를 제거하고 모든 정적 메소드를 해당 인터페이스로 이동하여 쉽게 찾고 사용할 수 있습니다.
자바 기능 인터페이스
게시물을 마치기 전에 Functional 인터페이스에 대해 간략하게 소개하고 싶습니다. 정확히 하나의 추상 메소드가있는 인터페이스를 기능 인터페이스라고합니다.
@FunctionalInterface
인터페이스를 기능 인터페이스로 표시하기 위해 새로운 주석 이 도입되었습니다. @FunctionalInterface
주석은 기능 인터페이스에 추상적 인 메소드가 실수로 추가되는 것을 방지하는 기능입니다. 선택이지만 사용하는 것이 좋습니다.
함수형 인터페이스는 오랫동안 기다려 왔으며, 람다 식을 사용하여 인스턴스화 할 수 있기 때문에 Java 8의 기능을 많이 찾고 있습니다. 람다 식 및 메소드 참조에 대한 대상 유형을 제공하기 위해 기능 인터페이스가 많은 새 패키지 java.util.function이 추가되었습니다. 향후 포스트에서 기능적 인터페이스와 람다 식을 살펴볼 것입니다.
자원 위치 :
답변
첫 번째 진술 (Java 8 릴리스 이후)을 제외한 모든 진술이 유효합니다.
Java 인터페이스의 메소드는 내재적으로 추상적이며 구현할 수 없습니다
설명서 페이지에서 :
인터페이스는 클래스와 유사하며 상수, 메소드 서명, 기본 메소드, 정적 메소드 및 중첩 유형 만 포함 할 수있는 참조
유형입니다.메소드 본문은 기본 메소드 및 정적 메소드에만 존재합니다.
기본 방법 :
인터페이스는 기본 메소드 를 가질 수 있지만 추상 클래스의 추상 메소드와 다릅니다.
기본 방법을 사용하면 라이브러리의 인터페이스에 새로운 기능을 추가하고 해당 인터페이스의 이전 버전 용으로 작성된 코드와 이진 호환성을 보장 할 수 있습니다.
기본 메소드가 포함 된 인터페이스를 확장하면 다음을 수행 할 수 있습니다.
- 기본 메소드를 언급하지 않아도 확장 인터페이스가 기본 메소드를 상속 할 수 있습니다.
- 기본 메소드를 다시 선언하면됩니다
abstract
. - 재정의하는 기본 방법을 재정의하십시오.
정적 방법 :
기본 메소드 외에도 인터페이스에서 정적 메소드를 정의 할 수 있습니다. (정적 메소드는 객체가 아니라 정의 된 클래스와 연관된 메소드입니다. 클래스의 모든 인스턴스는 정적 메소드를 공유합니다.)
이를 통해 라이브러리에서 헬퍼 메소드를 쉽게 구성 할 수 있습니다.
interface
보유 static
및 default
방법 에 대한 설명서 페이지의 예제 코드
import java.time.*;
public interface TimeClient {
void setTime(int hour, int minute, int second);
void setDate(int day, int month, int year);
void setDateAndTime(int day, int month, int year,
int hour, int minute, int second);
LocalDateTime getLocalDateTime();
static ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
아래 지침을 사용하여 인터페이스 또는 추상 클래스 사용 여부를 선택하십시오.
상호 작용:
- 계약 을 정의하려면 (바람직하게는 상태 비 저장-변수 없음)
- 관련없는 클래스를 연결 하는 기능이 있습니다.
- 공개 상수 변수를 선언하려면 ( 불변 상태 )
추상 클래스 :
-
밀접하게 관련된 여러 클래스간에 코드를 공유하십시오. 관계를 확립 한다 .
-
관련 클래스 간에 공통 상태 공유 (구체적인 클래스에서 상태를 수정할 수 있음)
관련 게시물:
이 예제들을 살펴보면
관련없는 클래스는 인터페이스를 통해 기능을 가질 수 있지만 관련 클래스는 기본 클래스의 확장을 통해 동작을 변경합니다.
답변
설명은 괜찮은 것처럼 보이지만 교과서에서 모두 읽은 것처럼 보일 수 있습니까? :-/
내가 더 걱정하는 것은 당신의 모범이 얼마나 견고 했습니까? 추상과 인터페이스의 거의 모든 차이점 을 포함 시키려 했습니까 ?
개인적으로, 나는이 링크를 제안합니다 :
http://mindprod.com/jgloss/interfacevsabstract.html#TABLE
철저한 차이점 목록 ..
앞으로의 인터뷰에서 당신과 다른 모든 독자들을 도울 수 있기를 바랍니다.