Другая форма перегрузки метода - PullRequest
4 голосов
/ 15 октября 2019

Я видел похожие вопросы к этому. Однако я не мог найти точного ответа на это. Я хочу знать лучший подход из следующих, основанных на обстоятельствах. Пожалуйста, объясните преимущества и недостатки случая 1 и случая 2.

Случай 1:

  public class Test {

    public void method1(String s) {
        System.out.println("String s");
    }

    public void method1(String s, String a) {
        System.out.println("String s" + "String a");
    }
}

Случай 2:

Я написал код следующим образом. Это простая логика, я хотел продемонстрировать только реализацию

public class Test {

    public void method1(String s) {
        new Test().methodImpl(s,null);
    }

    public void method1(String s, String a) {
        new Test().methodImpl(s,a);
    }

    public void methodImpl(String x , String y){
        if(y!=null){
            System.out.println("String s" + "String a");
        }else if(y==null){
            System.out.println("String s");
        }
    }
}

Ответы [ 3 ]

2 голосов
/ 15 октября 2019

Это не разные формы перегрузки как таковые;в Java существует только одна форма перегрузки (можно утверждать, что необязательные параметры C # достигают цели перегрузки), которая заключается в предоставлении нескольких методов с разными сигнатурами.

Ваши примеры слишком упрощены, чтобы их можно было объяснить, потому что они не сохраняют код. Случай 1 дублирует код, что означает, что он становится кошмаром обслуживания, а случай 2 делает список методов грязным, а реализацию - грязной, потому что он снова становится массовым оператором if с дублированным кодом, потому что вы сбросили все тела метода в if - получается 4строк кода в 7, и это ничего не решало, так как случай 1 представлял проблему;если вы найдете ошибку, вам все равно придется ее изменить в двух местах.

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

public SendEmail(string to, string message){
  SendEmail(to, message, null);
}

public SendEmail(string to, string message, Credentials c){

  MailClient mc = new MailClient();
  if(c == null){
    if(!to.endsWith("@local"))
      // throw exception; non local email delivery requires a credential
  } else {
    mc.Credentials = c;
  }

  mc.Send(to, message);
}

Здесь у нас есть одна реализация, мы делаем несколько операторов if, которые частично меняют поведение, вместо дублирования всего тела метода внутри блоков if / else, без повторяющегося кода, и мы имеемчем проще вызов перегрузки, тем более обширный

Многое в кодировании - это личный выбор, но именно так я и ожидал увидеть «перегрузку ради предоставления упрощенных версий вызова сложного метода». В отличие от этого, я не считаю, что ни один из ваших случаев имеет какие-либо конкретные преимущества по сравнению друг с другом, которые не устраняются их недостатками;случай 1 точнее, но дублирует код, случай 2 сложнее, чем необходимо, и дублирует код, но частично нацелен на маршрут «простые подписи, вызывающие сложные подписи»

1 голос
/ 15 октября 2019

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

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

new Test().method();

        or

new Test().method("This is a String.");

        or

new Test().method("This ", "is", " a", " string", " that", " will ", "be", " displayed.");

Он также может принимать одномерный (1D) строковый массив в качестве одного аргумента.

String[] stringArray = {This ", "is", " a", " string", " that", " will ", "be", " displayed."}; 
new Test().method(stringArray);

Если вы посмотрите на тест Класс ниже вы можете увидеть, что требуется только один метод:

public class Test {

    public void method(String... args) {
    if (args.length > 0) {
        // Build the string from the supplied string arguments...
        StringBuilder sb = new StringBuilder();
        for (String strg : args) {
            // A 'Ternary Operator' is used below in case an argument is null.
            sb.append(strg == null ? "" : strg);
        }
        System.out.println(sb.toString()); // Display built string in console.
    }

}

Что вы можете сделать, если параметр для этого метода был: Object... args?

Иногда я использую эту технику и для конструкторов классов, например:

public class Test {

    // Class Constructor
    public Test (String... args) {
        method(args);
    }

    public void method(String... args) {
    if (args.length > 0) {
        // Build the string from the supplied string arguments...
        StringBuilder sb = new StringBuilder();
        for (String strg : args) {
            // A 'Ternary Operator' is used below in case an argument is null.
            sb.append(strg == null ? "" : strg);
        }
        System.out.println(sb.toString()); // Display built string in console.
    }

} 

И для ее использования:

String[] stringArray = {"This ", "is", " a ", "string", " that", " will ", "be", " displayed."}; 
new Test(stringArray);  // You will notice a warning but it works.

or

new Test();  // You will notice a warning but it works.

or 

new Test("This is one Argument");  // You will notice a warning but it works.

or

new Test("This ", "is", " many ", "Arguments.");  // You will notice a warning but it works.

or 

Test test = new Test("This ", "is", " many ", "Arguments.");

or 

Test test = new Test();
test.method("This is one Argument");

or

String[] args = {"This ", "is", " many ", "Arguments."};
Test test = new Test(args);
test.method(args);

В последнем примере будет отображаться: This is many Arguments. дважды в консоли. Вы понимаете почему?

1 голос
/ 15 октября 2019

В случае 1 вам нужно написать повторяющийся логический код в каждом методе, а в случае 2 вы написали дополнительный метод, который мы можем уменьшить согласно приведенному ниже коду

открытый класс Test {

public void method1(String s) {
   method1(s,null);
}

public void method1(String s, String a) {
    if(a!=null){
       System.out.println("String s" + "String a");
    }else{
       System.out.println("String s");
    }
}

}

...