Java: Обоснование того, что класс Object не объявлен как абстрактный - PullRequest
20 голосов
/ 02 апреля 2009

Почему класс java.lang.Object не объявлен как абстрактный?

Конечно, для того, чтобы Объект был полезен, ему нужно добавить состояние или поведение, класс Объекта является абстракцией, и как таковой он должен был быть объявлен абстрактным ... почему они решили не делать этого?

Ответы [ 9 ]

17 голосов
/ 02 апреля 2009

Object полезен, даже если у него нет какого-либо состояния или поведения, специфичного для него.

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

public class Example {
    private final Object o = new Object();

    public void doSomething() {
        synchronized (o) {
            // do possibly dangerous stuff
        }
    }
}

Хотя этот класс немного прост в реализации (здесь неясно, почему полезно иметь явный объект, вы можете просто объявить метод synchronized), есть несколько случаев, когда это действительно полезно.

14 голосов
/ 03 апреля 2009

Анд, я думаю, что вы приближаетесь к этому - каламбур НЕ предназначен - с ненужной степенью абстракции. Я думаю, что этот (ИМХО) ненужный уровень абстракции - вот что вызывает здесь «проблему». Возможно, вы подходите к этому из математического теоретического подхода, где многие из нас подходят к этому из подхода «программист пытается решить проблемы». Я считаю, что это различие в подходах вызывает разногласия.

Когда программисты смотрят на практичность и как на самом деле реализовать что-то, бывает несколько раз, когда вам нужен какой-то совершенно произвольный Объект, фактический экземпляр которого не имеет никакого значения. Это просто не может быть нулевым. Пример, который я привел в комментарии к другому сообщению, - это реализация *Set (* == Hash или Concurrent или тип выбора), который обычно выполняется с использованием поддержки *Map и использованием Map ключи в качестве набора. Часто вы не можете использовать null в качестве значения Map, поэтому обычно используется статический экземпляр Object в качестве значения, которое будет игнорироваться и никогда не использоваться. Однако необходим некоторый ненулевой заполнитель.

Другое распространенное использование - ключевое слово synchronized, где некоторые Object необходимы для синхронизации, и вы хотите, чтобы ваш элемент синхронизации был полностью закрытым, чтобы избежать тупиковых ситуаций, когда разные классы непреднамеренно синхронизация по тому же замку. Очень распространенная идиома - выделить private final Object для использования в классе в качестве блокировки. Чтобы быть справедливым, в Java 5 и java.util.concurrent.locks.Lock и связанных с ними дополнениях, эта идиома измеримо менее применима.

Исторически сложилось так, что в Java было полезно создавать Object. Вы могли бы отметить, что с небольшими изменениями в дизайне или с небольшими изменениями API это больше не будет необходимо. Вы, вероятно, правы в этом.

И да, API мог бы предоставить класс Placeholder, который расширяет Object, не добавляя ничего вообще, для использования в качестве заполнителя для целей, описанных выше. Но - если вы расширяете Object, но ничего не добавляете, каково значение в классе, кроме того, что Object может быть абстрактным? Математически, теоретически, возможно, можно было бы найти значение, но с практической точки зрения, какое значение это добавит, чтобы сделать это?

В программировании бывают случаи, когда вам нужен объект, некоторый объект, любой конкретный объект, который не является нулевым, что-то, что вы можете сравнить с помощью == и / или .equals(), но вам просто не нужны никакие другие функции для этого объекта. Он существует только для того, чтобы служить уникальным идентификатором, а в остальном абсолютно ничего не делает. Object отлично справляется с этой ролью и (ИМХО) очень чисто.

Я бы предположил, что этот является одной из причин, по которой Object не был объявлен абстрактным: это прямо полезно, чтобы этого не было.

4 голосов
/ 02 апреля 2009

Определяет ли Object методы, которые классы, расширяющие его, должны реализовывать, чтобы быть полезными? Нет, и поэтому он не должен быть абстрактным.

Понятие абстрактного класса имеет четко определенное значение, которое не относится к Object.

3 голосов
/ 02 апреля 2009

Вы можете создать экземпляр Object для блокировки синхронизации:

Object lock = new Object();

void someMethod() {
  //safe stuff
  synchronized(lock) {
     //some code avoiding race condition
  }
}

void someOtherMethod() {
  //safe code
  synchronized(lock) {
    //some other stuff avoiding race condition
  }
}
2 голосов
/ 02 апреля 2009

Как объект может быть более оскорбительным, чем ноль?

Это хороший маркер места (так или иначе, нуля).

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

Я не говорю, что ноль - лучшая вещь с нарезанного хлеба - на днях я прочитал статью «Изобретателя», в которой обсуждалась цена / ценность концепции ноль ... (Я даже не думаю, что null можно было изобрести! Я думаю, кто-то где-то мог бы утверждать, что он изобрел ноль ...), просто способность создавать экземпляр Object не хуже, чем способность передавать NULL.

2 голосов
/ 02 апреля 2009

Я не уверен, что это причина, но она позволяет (или допускает, так как теперь есть лучшие способы сделать это) для объекта, который будет использоваться в качестве блокировки:

Object lock = new Object();

....


synchronized(lock)
{
}
1 голос
/ 02 апреля 2009

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

0 голосов
/ 03 июля 2013

Как всегда, Гуава приходит на помощь: с http://docs.guava -libraries.googlecode.com / git / javadoc / com / google / common / base / Optional.html Материал здесь можно использовать для уничтожения экземпляров null / Object для "ненулевого заполнителя" из кода.

Здесь есть полностью отдельные вопросы:

  • почему они не сделали Объект абстрактным?
  • сколько случится бедствия, если они решат сделать его абстрактным в будущем выпуске?
0 голосов
/ 07 февраля 2013

Там должно быть причиной, чтобы сделать класс абстрактным. Один из них - запретить клиентам создавать экземпляры класса и заставить их использовать только подклассы (по любым причинам). Другой вариант - если вы хотите использовать его как интерфейс, предоставляя абстрактные методы, которые подклассы должны реализовать. Вероятно, дизайнеры Java не видели таких причин, поэтому java.lang.Object остается конкретным.

...