Вопрос по java, static, interface, static-methods, inheritance – Почему реализация классов не может определить переопределяющий метод как статический?

3

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

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:* Спасибо за ответы, теперь я понимаю это лучше. По сути, я не должен пытаться заставить служебный класс (или, если на то пошло, класс фабрики) реализовать интерфейс (или, по крайней мере, не таким образом) ...

@TedHopp Технически это полная противоположность этому вопросу. biziclop
Это не оinterface метод является статичным, но позволяет моему сделатьimplementing метод статический. Чтобы я мог позвонитьMyImplementation.getInstance("foo"); вместоnew MyInterface("foo").getInstance("foo"); KidTempo
Подумайте об этом, как бы вы назвали переопределенный статический метод? biziclop
возможный дубликатWhy doesn't Java allow overriding of static methods? (или ещеWhy can't I declare static methods in an interface?) Ted Hopp
Обратите внимание, что в вашем примере подпись статического переопределения не совпадает с подписью метода интерфейса. Это даже не корректное переопределение. Tudor

Ваш Ответ

4   ответа
1

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

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

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

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

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

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

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

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

0

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

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

public void mymethod

а также

public static void mymethod

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

9

евозможно вызывать статические методы полиморфно, устраняя необходимость@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 решили не предоставлять этот «кусок магии».

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

Похожие вопросы