2016-08-24 4 views
2

Действительно ли этот дизайн действительно? Устаревший код приложения, поэтому просто пытайтесь реорганизовать, если это не нужно.Интерфейс и абстрактный класс разделяют тот же метод

public interface Interface { 
public void abc(); 
} 

public abstract class abClass implements Interface{ 
@Override 
public void abc(){ 
throw new UnsupportedOpException(NOT_IMPLEMENTED_MSG); 
} 

public class xyz extends abClass{ 
@Override 
public void abc(){ 
.......//some code here 

} 

Могу ли я избавиться от Interface? Не знаю, каково первоначальное намерение за этим дизайном. Когда вы хотели бы иметь same methods в обоих interface и abstract классах, которые в конечном итоге получаются overriden?

+3

Его действительно хорошая практика для использования таких интерфейсов. Посмотрите информацию о интерфейсах. –

+0

Хорошая практика ???? Для классов API да, в противном случае, просто накладные расходы. – davidxxx

+0

@davidhxxx Это точно я тоже думал .. –

ответ

0

void abc(); должен быть реализован либо абстрактным классом или унаследованных классами ...

нет никаких шансов, чтобы избавиться от этого ...

, если вы предпочитаете, вы можете переместить пустоту ABC(); как метод абстрактного класса ...

пересмотрел его и:

  • Блокировать подмену ВЗ, сделав его окончательным.

или

  • Делегат Обязанностью реализации в дочерних классах, делая его абстрактным тоже ..
+0

Это мой вопрос, даже если я удаляю интерфейс и удаляю «реализующий интерфейс» в абстрактном классе, он не нарушает код. Итак, почему я не могу определить его под абстрактным классом? –

0

Я думаю, с функциональной точки зрения программирования, это прекрасно, как есть. Имея implements Interface, это означает, что класс должен иметь метод с таким же именем. Тот факт, что он определен в abClass, означает, что вы не только говорите, что все классы, которые наследуют от abClass, должны иметь интерфейс, но также и вам не нужно переопределять его в каждом классе, если вы не хотите переопределить его.

Так что вы на самом деле не определить метод в Interface, но вы в abClass, и при определении метода в xyz, вы переопределение метода в abClass.

+0

Спасибо за ответ. Но почему я не могу избавиться от интерфейса?Пока абстрактный класс предоставляет определение метода, его унаследованный/переопределенный (если требуется) дочерние классы. –

+0

Ты вполне мог. Но что, если вы хотите определить другой класс, а также иметь метод, который делает что-то вроде того, что делает 'abc()'? И поскольку у него есть другой тип объекта, не имеет смысла, чтобы он наследовал любые другие методы в 'abClass'. Вы могли бы просто сказать «реализует интерфейс», и ему придется иметь «abc()». – Ishnark

+0

Пример: Интерфейс: 'IShape' имеет метод' public void area (int base, int height) '. У вас есть абстрактный класс «Четырехугольник» (с определением 'area (int base, int height)') и дочерние классы 'Square' (который переопределяет метод области) и' Rectangle' (который сохраняет метод area). Но вы хотите создать еще один класс - «Треугольник», и нет смысла наследовать метод Quadrilateral, поскольку он будет немного отличаться. Таким образом, 'class Triangle реализует IShape' позволит вам определить метод, называемый областью. – Ishnark

0

Интерфейс следует использовать за абстрактным классом, когда он предлагает что-то, что вам нужно, и что абстрактный класс не может предложить.
Создайте интерфейс без каких-либо конкретных причин, но поскольку вы считаете, что interface==OOP приносит издержки и доказывает, что вы неправильно поняли, что такое ООП.

В вашем случае, если в прикладном коде вы заметили, что вы можете удалить интерфейс за абстрактным классом и что у вас нет реального эффекта во время компиляции, вы можете задаться вопросом, является ли абстракция интерфейса не просто накладные расходы. Это может быть полезно, поскольку это не полезно. Я буду развивать его.

Использование интерфейса за абстрактным классом открывает возможности реализации: вы можете воспользоваться этим абстрактным классом, связанным с интерфейсом, но вы также можете реализовать интерфейс в конкретных классах без использования абстрактного класса, поэтому, как вы пожелаете. Написание реализации от A до Z может быть подходящим, поскольку оно не подходит в соответствии с нашими потребностями.

Лично я считаю, что интерфейс полезен позади абстрактного класса в двух случаях:

  • интерфейс является общим для на всех типах целевых конкретных классов, но абстрактный класс актуален не для всех типы целевых конкретных классов.

Например, при реализации декоратора у вас есть общий интерфейс для представления как украшенных классов, так и классов декораторов.
Классы декораторов имеют разную логику и данные из украшенных классов. Таким образом, наш абстрактный класс для классов декоратора или для украшенных классов может отличаться.

Здесь представлен простой пример для представления Decorator для документа.

Общий интерфейс:

public interface IDocumentInput { 

    void read(); 

    byte[] getBytes(); 

    String getStringContent(); 

} 

оформленный документ:

public class DocumentInput implements IDocumentInput { 

    private byte[] bytes; 

    public DocumentInput(byte[] bytes) { 
     this.bytes = bytes; 
    } 

    public byte[] getBytes() { 
     return bytes; 
    } 

    public void read() { 
    } 

    public String getStringContent() { 
     return new String(getBytes(),StandardCharsets.UTF_8); 
    } 

} 

абстрактный класс для декораторов:

public abstract class AbstractDocumentInputDecorator implements IDocumentInput { 

    protected IDocumentInput document; 
    protected byte[] bytes; 

    public AbstractDocumentInputDecorator(IDocumentInput document) { 
     this.document = document; 
    } 

    public byte[] getBytes() { 
     return bytes; 
    } 

    public final String getStringContent() { 
     return new String(getBytes(),StandardCharsets.UTF_8); 
    } 
} 

Бетон декоратор:

public class SecuredDocumentInputDecorator extends AbstractDocumentInputDecorator { 

    public SecuredDocumentInputDecorator(IDocumentInput document) { 
     super(document); 
    } 

    @Override 
    public void read() { 
     document.read(); 
     processUnsecuring(); 
    } 

    private void processUnsecuring() { 
     byte[] originalBytes = document.getBytes(); 
     bytes = Base64.decodeBase64(originalBytes); 
    } 

} 

В этом случае представляется логичным ввести интерфейс, потому что абстрактного класса недостаточно для представления общего поведения и/или данных всех конкретных классов.

  • Вы хотите предоставить разработчикам возможность создать собственную реализацию интерфейса с использованием или без использования абстрактного класса. В общем, желательно создать открытый API. Коллекции в классах JDK очень хорошо иллюстрируют это.
    Действительно, если вы хотите создать расширяемость интерфейса/контракта, когда вы предоставляете только абстрактный класс, разработчики, которые хотят создать свою реализацию, вынуждены использовать абстрактный класс, даже если они этого не хотят. Что нежелательно.

  • Вы используете библиотеку, которая заставляет вас использовать интерфейсы. Например, с помощью EJB 3.0 и Spring в этих первых версиях использование абстрактного класса или класса не позволяет использовать некоторые из их функций.

Смежные вопросы