Почему в Scala нет статических членов внутри класса? - PullRequest
50 голосов
/ 05 сентября 2011

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

Ответы [ 5 ]

56 голосов
/ 05 сентября 2011

O в OO означает «Объект», а не класс. Ориентация на объект - это все об объектах или экземплярах (если вы предпочитаете)

Статика не принадлежит объекту, ее нельзя наследовать, она не участвует в полиморфизме. Проще говоря, статика не является объектно-ориентированной.

Scala, с другой стороны, является объектно-ориентированным. Гораздо больше, чем Java, который особенно старался вести себя как C ++, чтобы привлечь разработчиков из этого языка.

Это хак, изобретенный C ++, который стремился соединить миры процедурного и ОО-программирования и который должен был быть обратно совместим с C. Он также допускал примитивы по тем же причинам.

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


Относительно , почему важно, чтобы по-настоящему ОО я собирался безбожно скопировать и вставить этот фрагмент из Билла Веннерса в список рассылки:

Хотя я смотрю на это так, что одноэлементные объекты позволяют вам делать статичные вещи там, где они нужны, очень лаконично, но также извлечь выгоду из наследования, когда вам нужно. Один пример это проще тестировать статические части вашей программы, потому что вы можете сделать черты, которые моделируют эти части и используют черты везде. Затем в производственная программа использует реализацию объекта Singleton тех черты, но в тестах используют фиктивные экземпляры.

Сам не мог бы сказать лучше!

Так что, если вы хотите создать что-то одно, то и статика, и синглтоны могут выполнить эту работу. Но если вы хотите, чтобы эта вещь откуда-то наследовала поведение, тогда статика вам не поможет.

По моему опыту, вы склонны использовать эту способность гораздо чаще, чем вы изначально думали, особенно после того, как вы некоторое время использовали Scala.

16 голосов
/ 05 сентября 2011

Я также разместил этот вопрос в группе пользователей scala, и Билл Веннерс, один из авторов ответа "Программирование в scala", поделился некоторыми соображениями.

Взгляните на это: https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/6vZJgi42TIMJ и https://groups.google.com/d/msg/scala-user/5jZZrJADbsc/oTrLFtwGjpEJ

Вот выдержка:

Я думаю один цель состояла в том, чтобы просто быть проще, имея каждое значение быть объектом, каждая операция вызов метода. Статика и примитивы Java особые случаи, что делает язык более «сложным» в некоторых чувство.

Но я думаю, что есть еще одна важная вещь - иметь что-то, что можно сопоставить с Java статика в Scala (потому что Scala нужна какая-то конструкция, которая отображается статика Java для взаимодействия), но это выигрывает от ОО наследование / полиморфизм. Синглтон объекты являются реальными объектами. Они могут расширить суперкласс или смешать в чертах и ​​быть переданы как таковые, но они также "статичны" по своей природе. Это оказывается очень удобным в практика.

Также взгляните на это интервью с Мартином Одерским (прокрутите вниз до раздела Объектно-ориентированные инновации в Scala) http://www.artima.com/scalazine/articles/goals_of_scala.html

Вот выдержка:

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

Подведем итог:

С точки зрения функционального программирования статические члены, как правило, считаются плохими (см. Этот пост Гилада Брача - отца java-дженериков. В основном это связано с побочными эффектами из-за глобального состояния). Но scala пришлось найти способ взаимодействия с Java (поэтому он должен был поддерживать статику) и минимизировать (хотя и не полностью избегать) глобальные состояния, создаваемые из-за статики, scala решила изолировать их в сопутствующие объекты.

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

4 голосов
/ 05 сентября 2011

Это то, что приходит мне в голову, когда я думаю о том, как статика может усложнять вещи:

1) Наследование, а также полиморфизм требуют особых правил.Вот пример:

// This is Java
public class A {
  public static int f() {
    return 10;
  }
}

public class B extends A {
  public static int f() {
    return 5;
  }
}

public class Main {
  public static void main(String[] args) {
    A a = new A();
    System.out.println(a.f());
    B b = new B();
    System.out.println(b.f());
    A ba = new B();
    System.out.println(ba.f());
   }
}

Если вы на 100% уверены в том, что распечатано, хорошо для вас.Остальные из нас могут смело полагаться на мощные инструменты, такие как @Override аннотация, которая, конечно, является необязательной и дружественной «Статический метод f () из типа A должен быть доступен статическим способом» предупреждение,Это приводит нас к

2) «Статический способ» доступа к вещам - это еще одно специальное правило, которое усложняет вещи.

3) Статические члены не могут быть абстрактными.Я думаю, у тебя не может быть всего, верно?

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

2 голосов
/ 05 сентября 2011

Это правда, статический член не существует, НО, можно связать одноэлементный объект с каждым классом:

class MyClass {
}

object MyClass {
}

для получения похожих результатов

1 голос
/ 06 декабря 2013

Объектно-ориентированное программирование - это все об объектах и ​​их состояниях (не затрагивая объекты с полным состоянием и объекты без состояния в Java).Я пытаюсь подчеркнуть «Статика не относится к объектам».Статические поля не могут быть использованы для представления состояния объекта , поэтому рационально отрываться от объектов.

...