Как вызвать обычный метод класса внутри static метода
Перейти к содержимому

Как вызвать обычный метод класса внутри static метода

  • автор:

Статические методы

Статические методы можно вызывать не используя ссылку на объект. В этом их ключевое отличие от обычных методов класса. Для объявления таких методов используется ключевое слово static . На методы, объявленные как static , накладывается следующие ограничения:

  • Они могут непосредственно вызывать только другие статические методы.
  • Им непосредственно доступны только статические переменные.
  • Они не могут делать ссылки типа this или super .

Пример использования статических методов:

public class StaticMethodClass < static int staticVar = 3; int nonStaticVar; public void nonStaticMethod() < System.out.println("Нестатический метод"); >static void staticMethod(int localVar) < System.out.println("localVar = " + localVar); System.out.println("staticVar = " + staticVar); //Нельзя обратиться к нестатической переменной из статического метода //System.out.println("nonStaticVar language-java">public class StaticMethodDemo < public static void main(String[] args) < StaticMethodClass.staticMethod(42); >>
  • Статические переменные
  • Статический блок
  • Java static import
  • Задания

Trustpilot
Комментарии

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

Статические свойства и методы

Мы также можем присвоить метод самому классу. Такие методы называются статическими.

В объявление класса они добавляются с помощью ключевого слова static , например:

class User < static staticMethod() < alert(this === User); >> User.staticMethod(); // true

Это фактически то же самое, что присвоить метод напрямую как свойство функции:

class User < >User.staticMethod = function() < alert(this === User); >;

Значением this при вызове User.staticMethod() является сам конструктор класса User (правило «объект до точки»).

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

Звучит не очень понятно? Сейчас все встанет на свои места.

Например, есть объекты статей Article , и нужна функция для их сравнения.

Естественное решение – сделать для этого статический метод Article.compare :

class Article < constructor(title, date) < this.title = title; this.date = date; >static compare(articleA, articleB) < return articleA.date - articleB.date; >> // использование let articles = [ new Article("HTML", new Date(2019, 1, 1)), new Article("CSS", new Date(2019, 0, 1)), new Article("JavaScript", new Date(2019, 11, 1)) ]; articles.sort(Article.compare); alert( articles[0].title ); // CSS

Здесь метод Article.compare стоит «над» статьями, как средство для их сравнения. Это метод не отдельной статьи, а всего класса.

Другим примером может быть так называемый «фабричный» метод.

Скажем, нам нужно несколько способов создания статьи:

  1. Создание через заданные параметры ( title , date и т. д.).
  2. Создание пустой статьи с сегодняшней датой.
  3. …или как-то ещё.

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

Такой как Article.createTodays() в следующем примере:

class Article < constructor(title, date) < this.title = title; this.date = date; >static createTodays() < // помним, что this = Article return new this("Сегодняшний дайджест", new Date()); >> let article = Article.createTodays(); alert( article.title ); // Сегодняшний дайджест

Теперь каждый раз, когда нам нужно создать сегодняшний дайджест, нужно вызывать Article.createTodays() . Ещё раз, это не метод одной статьи, а метод всего класса.

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

// предположим, что Article - это специальный класс для управления статьями // статический метод для удаления статьи по id: Article.remove();

Статические методы недоступны для отдельных объектов

Статические методы могут вызываться для классов, но не для отдельных объектов.

Например. такой код не будет работать:

// . article.createTodays(); /// Error: article.createTodays is not a function

Статические свойства

Новая возможность
Эта возможность была добавлена в язык недавно. Примеры работают в последнем Chrome.

Статические свойства также возможны, они выглядят как свойства класса, но с static в начале:

class Article < static publisher = "Илья Кантор"; >alert( Article.publisher ); // Илья Кантор

Это то же самое, что и прямое присваивание Article :

Article.publisher = "Илья Кантор";

Наследование статических свойств и методов

Статические свойства и методы наследуются.

Например, метод Animal.compare в коде ниже наследуется и доступен как Rabbit.compare :

class Animal < constructor(name, speed) < this.speed = speed; this.name = name; >run(speed = 0) < this.speed += speed; alert(`$бежит со скоростью $.`); > static compare(animalA, animalB) < return animalA.speed - animalB.speed; >> // Наследует от Animal class Rabbit extends Animal < hide() < alert(`$прячется!`); > > let rabbits = [ new Rabbit("Белый кролик", 10), new Rabbit("Чёрный кролик", 5) ]; rabbits.sort(Rabbit.compare); rabbits[0].run(); // Чёрный кролик бежит со скоростью 5.

Мы можем вызвать Rabbit.compare , при этом будет вызван унаследованный Animal.compare .

Как это работает? Снова с использованием прототипов. Как вы уже могли предположить, extends даёт Rabbit ссылку [[Prototype]] на Animal .

Так что Rabbit extends Animal создаёт две ссылки на прототип:

  1. Функция Rabbit прототипно наследует от функции Animal .
  2. Rabbit.prototype прототипно наследует от Animal.prototype .

В результате наследование работает как для обычных, так и для статических методов.

Давайте это проверим кодом:

class Animal <> class Rabbit extends Animal <> // для статики alert(Rabbit.__proto__ === Animal); // true // для обычных методов alert(Rabbit.prototype.__proto__ === Animal.prototype); // true

Итого

Статические методы используются для функциональности, принадлежат классу «в целом», а не относятся к конкретному объекту класса.

Например, метод для сравнения двух статей Article.compare(article1, article2) или фабричный метод Article.createTodays() .

В объявлении класса они помечаются ключевым словом static .

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

class MyClass < static property = . ; static method() < . >>

Технически, статическое объявление – это то же самое, что и присвоение классу:

MyClass.property = . MyClass.method = . 

Статические свойства и методы наследуются.

Для class B extends A прототип класса B указывает на A : B.[[Prototype]] = A . Таким образом, если поле не найдено в B , поиск продолжается в A .

Задачи

Класс расширяет объект?

важность: 3

Как мы уже знаем, все объекты наследуют от Object.prototype и имеют доступ к «общим» методам объекта, например hasOwnProperty .

class Rabbit < constructor(name) < this.name = name; >> let rabbit = new Rabbit("Rab"); // метод hasOwnProperty от Object.prototype alert( rabbit.hasOwnProperty('name') ); // true

Но что если мы явно напишем "class Rabbit extends Object" – тогда результат будет отличаться от обычного "class Rabbit" ?

Ниже пример кода с таким наследованием (почему он не работает? исправьте его):

class Rabbit extends Object < constructor(name) < this.name = name; >> let rabbit = new Rabbit("Кроль"); alert( rabbit.hasOwnProperty('name') ); // Ошибка

Сперва давайте разберёмся, почему код не работает.

Причина становится очевидна, если мы попытаемся запустить его. Унаследованный конструктор класса должен вызывать super() . В противном случае "this" будет не определён.

class Rabbit extends Object < constructor(name) < super(); // надо вызвать конструктор родителя, когда наследуемся this.name = name; >> let rabbit = new Rabbit("Кроль"); alert( rabbit.hasOwnProperty('name') ); // true

Но это ещё не все.

Даже после исправления есть важное различие между "class Rabbit extends Object" и class Rabbit .

Как мы знаем, синтаксис «extends» устанавливает 2 прототипа:

  1. Между "prototype" функций-конструкторов (для методов)
  2. Между самими функциями-конструкторами (для статических методов).

В случае с class Rabbit extends Object это значит:

class Rabbit extends Object <> alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true alert( Rabbit.__proto__ === Object ); // (2) true

Таким образом, Rabbit предоставляет доступ к статическим методам Object через Rabbit , например:

class Rabbit extends Object <> // обычно мы вызываем Object.getOwnPropertyNames alert( Rabbit.getOwnPropertyNames() ); // a,b

Но если явно не наследуем от объекта, то для Rabbit.__proto__ не установлено значение Object .

class Rabbit <> alert( Rabbit.prototype.__proto__ === Object.prototype ); // (1) true alert( Rabbit.__proto__ === Object ); // (2) false (!) alert( Rabbit.__proto__ === Function.prototype ); // как у каждой функции по умолчанию // ошибка - нет такой функции у Rabbit alert( Rabbit.getOwnPropertyNames() ); // Ошибка

Таким образом, в этом случае у Rabbit нет доступа к статическим методам Object .

Кстати, у Function.prototype также есть «общие» методы, такие как call , bind и т. д. Они в конечном итоге доступны в обоих случаях, потому что для встроенного конструктора Object Object.__proto__ === Function.prototype .

Пример на картинке:

Короче говоря, есть два отличия:

class Rabbit class Rabbit extends Object
необходимо вызвать super() в конструкторе
Rabbit.__proto__ === Function.prototype Rabbit.__proto__ === Object

static

This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2017 .

Для того, чтобы объявить статический метод класса, необходимо использовать ключевое слово static.

Синтаксис

static methodName()

Описание

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

Вызов статических методов

Вызов из другого статического метода

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

class StaticMethodCall  static staticMethod()  return "Вызван статический метод"; > static anotherStaticMethod()  return this.staticMethod() + " из другого статического метода"; > > StaticMethodCall.staticMethod(); // 'Вызван статический метод' StaticMethodCall.anotherStaticMethod(); // 'Вызван статический метод из другого статического метода' 

Вызов из конструктора класса и других методов

Статические методы недоступны напрямую, используя ключевое слово this из нестатических методов. Вам нужно вызвать их с помощью имени класса: CLASSNAME.STATIC_METHOD_NAME() или вызовом метода как свойства конструктора: this.constructor.STATIC_METHOD_NAME() .

class StaticMethodCall  constructor()  console.log(StaticMethodCall.staticMethod()); // 'вызван статический метод.' console.log(this.constructor.staticMethod()); // 'вызван статический метод.' > static staticMethod()  return "вызван статический метод."; > > 

Примеры

Следующий пример демонстрирует:

  1. Как статический метод реализуется в классе.
  2. Как переопределить статический метод при наследовании.
  3. Как можно и как нельзя вызывать статические методы.
class Triple  static triple(n)  if (n === undefined)  n = 1; > return n * 3; > > class BiggerTriple extends Triple  static triple(n)  return super.triple(n) * super.triple(n); > > console.log(Triple.triple()); // 3 console.log(Triple.triple(6)); // 18 var tp = new Triple(); console.log(BiggerTriple.triple(3)); // 81 (не затрагивается экземпляром родителя) console.log(tp.triple()); // Выведет сообщение, что "tripple" не является // функцией ('tp.tripple is not a function'). 

Спецификации

Specification
ECMAScript Language Specification
# sec-class-definitions

Совместимость с браузерами

BCD tables only load in the browser

Смотрите также

  • class expression
  • class declaration
  • Classes

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 6 янв. 2024 г. by MDN contributors.

Your blueprint for a better internet.

Как вызвать статический метод java

то при вызове его из другого класса нужно указать имя класса App :

// Где-то в другом месте программы class SomeName  public static void someMethod  // Для вызова статического метода нужно // указывать имя класса App.greeting(); > > 

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

class App  public static String greeting()  return "just a string"; > public static void main(String[] args)  // Тот же класс, поэтому имя не обязательно greeting(); > > 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *