Java: интерфейс против абстрактного класса (относительно полей)

Из того, что я собрал, я хочу заставить класс использовать частные частные поля (и методы). Мне нужен абстрактный класс, потому что интерфейс только объявляет общедоступные/статические/окончательные поля и методы. Правильно??

Я только что начал свой первый большой проект java и хочу, чтобы я не собирался причинять себе боль позже:)

Ответ 1

Достаточно распространено предоставление обоих, так что в итоге вы получите:

public interface Sendable {
    public void sendMe();
}

и

public abstract class AbstractSender implements Sendable {
    public abstract void send();

    public void sendMe() {
        send(this.toString());
    }
}

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

Ответ 2

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

Ответ 3

Частные поля и методы не могут использоваться подклассами (кроме случаев, когда они также являются внутренними классами). Однако вы можете защитить их.

Ответ 4

Интерфейс определяет именно это - интерфейс (контракт) с миром вне класса реализации. Общественные методы (абстрактного или нет) суперкласса делают то же самое. Вы не должны пытаться требовать, чтобы подклассы имели определенные частные члены - вы пытаетесь указать реализацию, о которой ООП хочет избежать.

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

Даже если вы наследуете абстрактный класс, вы не сможете получить доступ к его частным полям/методам.

Ответ 5

Это правильно. Но это не обязательно одно из решений, вы можете комбинировать преимущества интерфейсов и абстрактных классов, предоставляя скелетную реализацию вместе с вашим интерфейсом. Вы можете найти очень интересное описание этого подхода в Effective Java, 2nd Ed., Item 18 ( "Предпочитаете интерфейсы для абстрактных классов" ).

Ответ 6

Это правильно. Интерфейсы предназначены для общественного потребления. И частная реализация должна быть в абстрактном (или конкретном) классе.

Ответ 7

Если вы когда-либо находите, что угадываете, какой из них выбрать, я предлагаю ошибиться на стороне интерфейсов. Лучше иметь интерфейс, который должен был быть абстрактным классом, чем наоборот.

Ответ 8

Интерфейсы определяют контракт на поведение. Это то, что нужно, а не атрибуты.

Ответ 9

Я хочу заставить класс использовать частные частные поля (и методы)

Эта часть вашего вопроса сомнительна: почему вы думаете, что хотите сделать это?

Частные члены

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

Ответ 10

Если вы хотите, чтобы подкласс определял определенные методы, использование интерфейса будет делать трюк. Как говорили другие, это не столько о том, как это делает подкласс, а только в том, что он это сделает.

Ответ 11

Если вы хотите, чтобы класс использовал определенные поля или методы другого класса, вы можете объявить их защищенными.

    public abstract class A {

      protected Object thing;
    }

можно получить доступ другим классом в том же пакете (может быть расширение класса A или нет)

A a = new A();
a.thing.toString();

На самом деле это не "заставляет" другой класс использовать его, но больше похоже на "включение".