Почему статические методы не могут быть абстрактными в Java - PullRequest
557 голосов
/ 16 декабря 2008

Вопрос в Java, почему я не могу определить абстрактный статический метод? например

abstract class foo {
    abstract void bar( ); // <-- this is ok
    abstract static void bar2(); //<-- this isn't why?
}

Ответы [ 24 ]

2 голосов
/ 17 июля 2015

Абстрактный класс не может иметь статический метод, потому что абстракция выполняется для достижения ДИНАМИЧНОЙ СВЯЗИ, в то время как статические методы статически связаны с их функциональностью. Статический метод означает поведение не зависит от переменной экземпляра, поэтому нет экземпляра / объекта Требуется. Просто методы class.Static принадлежат классу, а не объекту. Они хранятся в области памяти, известной как PERMGEN, откуда она используется для каждого объекта. Методы в абстрактном классе динамически связаны с их функциональностью.

1 голос
/ 29 ноября 2018

Поскольку абстрактный класс является концепцией OOPS, а статические члены не являются частью OOPS ....
Теперь мы можем объявить статические методы завершения в интерфейсе и выполнить интерфейс, объявив метод main внутри интерфейса

interface Demo 
{
  public static void main(String [] args) {
     System.out.println("I am from interface");
  }
}
1 голос
/ 16 декабря 2008

Статический метод может быть вызван без экземпляра класса. В вашем примере вы можете вызвать foo.bar2 (), но не foo.bar (), потому что для bar вам нужен экземпляр. Следующий код будет работать:

foo var = new ImplementsFoo();
var.bar();

Если вы вызываете статический метод, он всегда будет выполняться с одним и тем же кодом. В приведенном выше примере, даже если вы переопределите bar2 в ImplementsFoo, вызов var.bar2 () выполнит foo.bar2 ().

Если bar2 теперь не имеет реализации (это означает абстрактное значение), вы можете вызвать метод без реализации. Это очень вредно.

1 голос
/ 29 августа 2015

Я считаю, что нашел ответ на этот вопрос в форме того, почему методы интерфейса (которые работают как абстрактные методы в родительском классе) не могут быть статичными. Вот полный ответ (не мой)

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

Если вы вызываете статический метод, вы уже знаете класс, в котором он реализован, или любые его прямые подклассы. Если вы определите

abstract class Foo {
    abstract static void bar();
}

class Foo2 {
    @Override
    static void bar() {}
}

Тогда любой Foo.bar(); вызов явно недопустим, и вы всегда будете использовать Foo2.bar();.

Имея это в виду, единственная цель статического абстрактного метода состояла бы в том, чтобы заставить подклассы реализовать такой метод. Сначала вы можете подумать, что это ОЧЕНЬ неправильно, но если у вас есть параметр общего типа <E extends MySuperClass>, было бы неплохо гарантировать через интерфейс, что E может .doSomething(). Имейте в виду, что из-за стирания типов дженерики существуют только во время компиляции.

Так, это было бы полезно? Да, и, возможно, именно поэтому Java 8 допускает статические методы в интерфейсах (хотя только с реализацией по умолчанию). Почему бы не абстрагировать статические методы с реализацией по умолчанию в классах? Просто потому, что абстрактный метод с реализацией по умолчанию на самом деле является конкретным методом.

Почему бы не абстрактные / интерфейсные статические методы без реализации по умолчанию? По-видимому, просто из-за того, как Java определяет, какой блок кода он должен выполнить (первая часть моего ответа).

0 голосов
/ 13 июня 2018

Объявление метода как static означает, что мы можем вызвать этот метод по имени класса, а если этот класс также abstract, нет смысла вызывать его, так как он не содержит никакого тела, и, следовательно, мы не можем объявите метод как static и abstract.

0 голосов
/ 09 марта 2018

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

0 голосов
/ 13 мая 2017

Поскольку abstract - это ключевое слово, которое применяется к абстрактным методам, они не указывают тело. И если говорить о статическом ключевом слове, оно относится к области классов.

0 голосов
/ 16 февраля 2013

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

0 голосов
/ 05 декабря 2015

Обычные методы могут быть абстрактными, если они должны быть переопределены подклассами и снабжены функциональностью. Представьте, что класс Foo расширен на Bar1, Bar2, Bar3 и т. Д. Итак, у каждого будет своя версия абстрактного класса в соответствии со своими потребностями.

Теперь статические методы по определению принадлежат классу, они не имеют ничего общего с объектами класса или объектами его подклассов. Им даже не нужно, чтобы они существовали, их можно использовать без создания экземпляров классов. Следовательно, они должны быть готовы к работе и не могут зависеть от подклассов для добавления к ним функциональности.

0 голосов
/ 28 сентября 2015

Потому что «абстрактный» означает, что метод предназначен для переопределения, и нельзя переопределять «статические» методы.

...