Почему реализация классов не может определить переопределяющий метод как статический?

Я запутался, почему не допускается следующее:

public interface MyInterface {
  MyInterface getInstance(String name);
}

public class MyImplementation implements MyInterface {
  public MyImplementation(String name) {
  }
  @Override
  public static MyInterface getInstance(String name) { // static is not allowed here
    return new MyImplementation(name)
  }
}

Я понимаю, почему метод в интерфейсе не может быть статичным, но почему не может быть переопределяющий метод?

Я хочу, чтобы все классы реализовалиgetInstance(String name) метод, но в настоящее время я ограничен возможностью вызова метода только в том случае, если объект уже был создан, какой тип побеждает цель ...

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

 biziclop02 июл. 2012 г., 17:33
Подумайте об этом, как бы вы назвали переопределенный статический метод?
 biziclop02 июл. 2012 г., 17:35
@TedHopp Технически это полная противоположность этому вопросу.
 Tudor02 июл. 2012 г., 17:48
Обратите внимание, что в вашем примере подпись статического переопределения не совпадает с подписью метода интерфейса. Это даже не корректное переопределение.
 KidTempo02 июл. 2012 г., 17:36
Это не оinterface метод является статичным, но позволяет моему сделатьimplementing метод статический. Чтобы я мог позвонитьMyImplementation.getInstance("foo"); вместоnew MyInterface("foo").getInstance("foo");
 Ted Hopp02 июл. 2012 г., 17:33

Ответы на вопрос(4)

Решение Вопроса

евозможно вызывать статические методы полиморфно, устраняя необходимость@Override.

Обратите внимание, что этот подход не универсален для всех языков: например, вы можете переопределитьclass methods в Objective-C и в структурах Apple для какао этот механизм хорошо используется для настройки их «фабрики» классы. Однако в Java, методы классов C ++ и C # не поддерживают полиморфное поведение.

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

public class MyImplementation implements MyInterface {
    public MyImplementation(String name) {
    }
    @Override
    public MyInterface getInstance() { // static is not allowed here
        return getInstanceImpl();
    }
    public static getInstanceImpl() {
        return new MyImplementation(name)
    }
}

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

 02 июл. 2012 г., 18:00
+1 за упоминание о том, что это не универсально. Именно синтаксис вызова Java делает этот подход невозможным, а не теоретической границей.

о не имеет особого смысла. Представьте себе этот вариант использования, предполагая, что вы хотите, было бы возможно:

public void foo(MyInterface i) {
    i.getInstance("abc");
}

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

A a = new A();
foo(a);

сейчас внутриfoo static переопределениеgetInstance вызывается по экземпляру классаA, Так что теперь я застрял с созданием объекта просто для вызова статического метода.

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

 30 нояб. 2013 г., 00:47
"Это не имеет особого смысла" : было бы - и это было бы чертовски полезно. Вопрос в том, почему он не реализован:stackoverflow.com/questions/20291984/…, Посмотрите, как можно назвать эти переопределения

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

type интерфейса. Это означаетinstances необходимо иметь методы, определенные типом, а не классом экземпляров.

Другими словами,

public void mymethod

а также

public static void mymethod

НЕ одно и то же объявление метода. Они совершенно разные. Еслиmymethod определяется на интерфейсе, второе определение просто не удовлетворяет реализации интерфейса.

Ваш ответ на вопрос