Почему объектные объекты более объектно-ориентированные?
В Программирование в Scala: всестороннее пошаговое руководство, автор сказал:
Один из способов, в котором Scala больше объектно-ориентированной, чем Java, классы в Scala не могут иметь статические члены. Вместо этого Scala имеет singleton объекты.
Почему объект singleton более объектно-ориентированный? Какая польза от использования статических элементов, но одиночных объектов?
Ответы
Ответ 1
Попытка "большой картины"; большая часть из них была освещена в других ответах, но, похоже, не существует единого всеобъемлющего ответа, который объединяет все и объединяет точки. Итак, здесь идет...
Статические методы в классе не являются методами для объекта, это означает, что:
Вся цель объектов состоит в том, что они могут наследовать от родительских объектов, реализовывать интерфейсы и передаваться в качестве аргументов. Статические члены не имеют ни одного из этих свойств, поэтому они не являются объектно-ориентированными, они немного больше, чем пространство имен.
Объекты Singleton, с другой стороны, являются полноправными членами сообщества объектов.
Еще одно очень полезное свойство синглтонов заключается в том, что их можно легко изменить в какой-то более поздний момент времени, чтобы не быть одиночными, это особенно болезненный рефакторинг, если вы начинаете со статических методов.
Представьте, что вы разработали программу для печати адресов и представляли взаимодействия с принтером с помощью статических методов в каком-то классе, а затем вы захотите добавить второй принтер и разрешить пользователю выбирать, какой из них использовать. Это было бы не очень весело!
Ответ 2
Объекты Singleton ведут себя как классы в том, что они могут расширять/реализовывать другие типы.
Невозможно сделать это на Java с помощью только статических классов - это довольно сахара над шаблоном singleton One с getInstance
, который позволяет (по крайней мере) более ярких пространств имен/стабильных идентификаторов и скрывает различие.
Ответ 3
Подсказка: он называется object -ориентированным программированием.
Серьезно.
Возможно, мне не хватает чего-то принципиально важного, но я не понимаю, что такое суета: объекты более объектно-ориентированные, чем не-объекты, потому что они являются объектами. Вам действительно нужно объяснение?
Примечание: Хотя это точно звучит так, я действительно не пытаюсь казаться самодовольным здесь. Я просмотрел все остальные ответы, и я нашел их ужасно запутанными. Для меня очевидно, что объекты и методы более объектно-ориентированы, чем пространства имен и процедуры (что и есть статические "методы" ) по самому определению "объектно-ориентированного".
Альтернативой наличию одноэлементных объектов было бы создание самих объектов классов, например. Ruby, Python, Smalltalk, Newspeak do.
Ответ 4
Для статических членов нет объекта. Класс действительно просто пространство имен.
В одноэлементном режиме всегда есть хотя бы один объект.
Честно говоря, он раскалывает волосы.
Ответ 5
Более объектно ориентированный в том смысле, что данный класс Scala, каждый вызов метода является вызовом метода для этого объекта. В Java статические методы не взаимодействуют с состоянием объекта.
Фактически, учитывая объект a
класса a
со статическим методом m()
, он считал, что неправильная практика вызывает a.m()
. Вместо этого рекомендуется называть a.m()
(я считаю, что Eclipse предоставит вам предупреждение). Статические методы Java нельзя переопределить, их можно просто скрыть другим способом:
class A {
public static void m() {
System.out.println("m from A");
}
}
public class B extends A {
public static void m() {
System.out.println("m from B");
}
public static void main(String[] args) {
A a = new B();
a.m();
}
}
Что будет печатать a.m()
?
В Scala вы должны придерживаться статических методов в сопутствующих объектах A и B, и намерение будет более четким, поскольку вы прямо ссылаетесь на спутника A или B.
Добавление того же примера в Scala:
class A
object A {
def m() = println("m from A")
}
class B extends A
object B {
def m() = println("m from B")
def main(args: Array[String]) {
val a = new B
A.m() // cannot call a.m()
}
}
Ответ 6
Существует некоторая разница, которая может быть важной в некоторых сценариях. В Java вы
не может переопределить статический метод, поэтому, если бы у вас был класс со статическими методами, вы бы не смогли настроить и переопределить часть его поведения. Если вы использовали одноэлементный объект, вы можете просто подключить синглтон, созданный из подкласса.
Ответ 7
Это действительно маркетинговая штука. Рассмотрим два примера:
class foo
static const int bar = 42;
end class
class superfoo
Integer bar = ConstInteger.new(42);
end class
Теперь, какие здесь наблюдаемые различия?
- на хорошо организованном языке, создается дополнительное хранилище.
- Foo.bar и Superfoo.bar имеют точно такие же сигнатуры, доступ и т.д.
- Superfoo.bar может быть выделен по-разному, но что деталь реализации
Это напоминает мне о религиозных войнах 20 лет назад о том, действительно ли С++ или Java были "реально" объектно-ориентированными, поскольку ведь обе обнаженные примитивные типы, которые не являются "действительно" объектами, - так, например, вы не можете наследует от int
, но может от Integer
.