Действительно ли перегрузка - единственный способ получить значения по умолчанию для параметров метода в Java? - PullRequest
2 голосов
/ 06 марта 2009

Я довольно новичок в Java и из Python и PHP, я привык к значениям по умолчанию для параметров функции.

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

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

Я помню, что это уже раздражало меня в некоторых кратких экскурсиях по C ++ и ActionScript. Теперь, есть ли более опытные разработчики Java для этого?

Мне кажется, что технически на вопрос ответила сумма всех сообщений как "Да, это так". Я открыл пост вики внизу, чтобы собрать различные альтернативные решения, пожалуйста, внесите свой вклад, если хотите. Я нашел все это очень полезным как вдохновение и как примеры изучения типичных конструкций Java.

Ответы [ 7 ]

7 голосов
/ 06 марта 2009

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

Это можно увидеть в действии в стандартных библиотеках с классами ProcessBuilder и Process.

3 голосов
/ 06 марта 2009

см. Varargs

http://www.java -tips.org / Java-SE-советы / java.lang / с использованием-на-языке с переменным числом аргументов-feature.html

(обновленный URL; этот комментарий добавлен, потому что для стекопотока требуется> 30 символов)

2 голосов
/ 06 марта 2009

Чтобы сделать это проще, я создал аннотацию для значений по умолчанию и процессор аннотаций, который генерирует суперкласс с перегруженными методами. Например:

protected void process(
    Processor processor,
    String item,
    @Default("Processor.Size.LARGE") Size size,
    @Default("red") String color,
    @Default("1") int quantity) {
        ...
}

, который генерирует (в сгенерированном суперклассе)

protected void process(sample.Processor processor, java.lang.String item)  {
    process(processor, item, Processor.Size.LARGE, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size)  {
    process(processor, item, size, "red", 1);
}
protected void process(sample.Processor processor, 
                       java.lang.String item, 
                       sample.Processor.Size size, 
                       java.lang.String color)  {
    process(processor, item, size, color, 1);
}
protected abstract void process(sample.Processor processor, 
                                java.lang.String item, 
                                sample.Processor.Size size, 
                                java.lang.String color, 
                                int quantity) ;

См. http://code.google.com/p/javadude/wiki/Annotations - Скотт

1 голос
/ 06 марта 2009

Может быть очень трудно попытаться перевести ваш процесс хотя бы из одного языка в другой. Вы можете, как отмечали другие, сделать некоторые обходные пути, чтобы, возможно, получить то, что вы хотите ... но чем раньше вы «примете» способ, которым Java разработана для работы, тем лучше вы будете работать при работе с Java. *

Мне приходилось делать кое-что из PHP ... досадно раздражало меня, что я не мог заставить его делать то, что хотел ... так что все идет в обе стороны.

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

В первые дни C ++ люди пытались убедить C ++ вести себя как Smalltalk ... не получалось слишком хорошо. В первые дни, если люди Java пытались взять свои знания C ++ и использовать их в Java ... не получалось слишком хорошо (что вдвойне расстраивает, так как языки очень похожи на поверхности).

Мой совет: научитесь программировать как Java-разработчик, а не как PHP-разработчик.

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

0 голосов
/ 20 августа 2016

Да, oop - это перегрузка, которая является единственным способом использования параметра по умолчанию в Java. Но вот хак для тебя. Если вы используете перегрузку и хотите иметь параметр по умолчанию. Тогда вы в конечном итоге

public void methodA(A arg1) { }
public void methodA( B arg2,) { }
public void methodA(C arg3) { }
public void methodA(A arg1, B arg2) { }
public void methodA(A arg1, C arg3) { }
public void methodA( B arg2, C arg3) { }
public void methodA(A arg1, B arg2, C arg3) { }

Но используя varargs

public class DefaultValue
{
 public static void main(String[] args)
  {
       defaultParameter();
       defaultParameter(true);
  }

  public static void defaultParameter(Boolean …gender)
  {
       boolean genderBoolean = false; // It is the default value you want to give
       if(1 == gender.length)
       {
            genderBoolean = gender[0]; // Overrided Value
      }
       System.out.println(genderBoolean);
 }
}

Приведенный выше код будет

false
true

Дополнительные примеры и пояснения см. В разделе java-default-parameter-values ​​

0 голосов
/ 06 марта 2009

Похоже, «Да, это так», кроме:

Подобные эффекты могут быть достигнуты с помощью varargs , как предложено Полом Уиланом, или путем определения дополнительного типа, несущего параметры в виде полей с соответствующими значениями по умолчанию, как предложено Джоном Скитом. Борис Павлович добавляет, что его тип может быть внутренним статическим классом, чтобы аккуратно держать вещи в нужном месте.

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

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

Специальный тип, содержащий параметры, кажется наиболее полезным, если результирующий тип может иметь другое использование, а не просто передаваться одному конкретному методу, или когда это более сложный набор параметров. Если есть 2-4 параметра, а некоторые могут иметь значения по умолчанию, перегрузку все же немного удобнее, но это может быть вопросом личного вкуса.

0 голосов
/ 06 марта 2009

Пока вы кодируете OO, вы не пропустите значения по умолчанию в Java. Аргументы по умолчанию удобны только в процедурном стиле кодирования.

В ОО вместо передачи состояния через методы / процедуры состояние уже находится в вызываемом объекте или объектах, которые вы передаете в качестве параметров. Большую часть времени вам нужно не более 1 или 2 параметров в ваших методах.

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

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