Почему я не могу иметь абстрактный и статический метод в одном классе в Java - PullRequest
2 голосов
/ 10 января 2012

У меня есть следующий класс:

public abstract class A
{
  public abstract String doSomething(String X, String Y);
  public static String doSomething(String X, String Y){return X + Y;}
  ...
}

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

Я знаю, что мог бы, вероятно, добавить интерфейс в микс, но я не совсем понимаю, что не так с моими абстрактными и статическими методами, существующими в одном классе. Что с этим не так?

Ответы [ 3 ]

8 голосов
/ 10 января 2012

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

System.out.println(String.valueOf(true)); // Prints "true".
System.out.println("".valueOf(true)); // Prints "true", unfortunately.

Таким образом, следующий кажущийся действительный код не будет знать, какой из этих методов вызывать:

A a = getInstanceOfConcreteSubclassOfA();
a.doSomething(null, null); // Compiler can't decide which method to call...

К сожалению, это лишь один из немногих уродливых уголков языка Java.

3 голосов
/ 10 января 2012

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

public String doSomething(String X, String Y){return X + Y;}
public static String doSomething(String X, String Y){return X + Y;}

также будет незаконным.

(Это имеет смысл, если учесть, что вы можете вызывать статический метод «на» фактическом экземпляре или, в этом отношении, на любом выражении соответствующего типа. Компилятор переводит ((A)null).staticMethod() в A.staticMethod() .)

1 голос
/ 10 января 2012

Каждый метод имеет подпись, состоящую из:

method name
parameter type
Return type

Если два метода имеют одинаковую подпись, это вызовет ошибку.

слово static не не вмешиваться в сигнатуру метода так же, как const.

...