Java: интерфейс против абстрактного класса (в отношении полей) - PullRequest
10 голосов
/ 20 января 2009

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

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

Ответы [ 11 ]

20 голосов
/ 20 января 2009

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

20 голосов
/ 20 января 2009

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

public interface Sendable {
    public void sendMe();
}

и

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

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

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

4 голосов
/ 20 января 2009

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

3 голосов
/ 20 января 2009

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

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

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

1 голос
/ 20 января 2009
Я хочу заставить класс использовать определенные приватные поля (и методы)

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

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

1 голос
/ 20 января 2009

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

1 голос
/ 20 января 2009

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

1 голос
/ 20 января 2009

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

1 голос
/ 20 января 2009

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

0 голосов
/ 13 апреля 2010

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

    public abstract class A {

      protected Object thing;
    }

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

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

Это на самом деле не «заставляет» другой класс использовать его, скорее как «включение».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...