Ключевое слово static
изменяет жизненный цикл метода или переменной внутри класса. Метод / переменная static
создается во время загрузки класса. Метод или переменная, которая не объявлена как static
, создается только тогда, когда класс создается как объект, например, с помощью оператора new
.
Жизненный цикл класса в широком смысле, is:
new
, используя класс, чтобы сделать экземпляр класса как фактического объекта, а затем, когда он сделан с объектом Чтобы иметь начальную точку входа для приложения, Java приняла соглашение о том, что программа Java должна иметь класс, который содержит метод с согласованным или специальным именем. Этот специальный метод называется main()
. Поскольку метод должен существовать независимо от того, был ли экземпляр класса, содержащего основной метод, метод main()
должен быть объявлен с помощью модификатора static
, так что, как только класс будет загружен, доступен метод main()
.
В результате, когда вы запускаете приложение Java с помощью командной строки, например java helloworld
, происходит серия действий. Прежде всего запускается и инициализируется виртуальная машина Java. Затем файл helloworld.class, содержащий скомпилированный Java-код, загружается в виртуальную машину Java. Затем виртуальная машина Java ищет метод в классе helloworld
, который называется main(String [] args)
. этот метод должен быть static
, так что он будет существовать, даже если класс фактически не был создан как объект. Виртуальная машина Java не создает экземпляр класса, создавая объект из класса. Он просто загружает класс и запускает выполнение по методу main()
.
Итак, вам нужно создать экземпляр вашего класса в качестве объекта, а затем вы можете получить доступ к методам и переменным класса, у которых нет был объявлен с помощью модификатора static
. После того, как ваша Java-программа началась с функции main()
, вы можете использовать любые переменные или методы, которые имеют модификатор static
, поскольку они существуют как часть загружаемого класса.
Однако эти переменные и методы класса, которые находятся вне метода main()
, которые не имеют модификатора static
, не могут использоваться до тех пор, пока экземпляр класса не будет создан как объект в рамках метода main()
. После создания объекта вы можете использовать переменные и методы объекта. Попытка использовать переменные и методы класса, которые не имеют модификатора static
, не проходя через объект класса, улавливается компилятором Java во время компиляции и помечена как ошибка.
import java.io.*;
class helloworld {
int myInt; // this is a class variable that is unique to each object
static int myInt2; // this is a class variable shared by all objects of this class
static void main (String [] args) {
// this is the main entry point for this Java application
System.out.println ("Hello, World\n");
myInt2 = 14; // able to access the static int
helloworld myWorld = new helloworld();
myWorld.myInt = 32; // able to access non-static through an object
}
}
Для этого вы можете использовать debug_backtrace (). Это немного, но для целей отладки полезно.
class normalClass {
public function someMethod() {
$trace = debug_backtrace();
$trace[1]->object->doSomething();
}
}
У вас есть несколько вариантов. Вы можете использовать агрегацию так
class normalClass
{
protected $superClass;
public function __construct( superClass $superClass )
{
$this->superClass = $superClass;
}
public function someMethod()
{
$this->superClass->doSomething();
}
}
class superClass
{
public function __construct()
{
$inst = new normalClass( $this );
$inst->someMethod();
}
public function doSomething()
{ //this method shall be be accessed by domeMethod form normalClass
}
}
Или просто прямолинейный сеттер
class normalClass
{
protected $superClass;
public function setSuperClass( superClass $superClass )
{
$this->superClass = $superClass;
}
public function someMethod()
{
if ( !isset( $this->superClass ) )
{
throw new Exception( 'you must set a superclass' );
}
$this->superClass->doSomething();
}
}
class superClass
{
public function __construct()
{
$inst = new normalClass();
$inst->setSuperClass( $this );
$inst->someMethod();
}
public function doSomething()
{ //this method shall be be accessed by domeMethod form normalClass
}
}
В зависимости от вашего варианта использования вы можете передать экземпляр только функции:
class normalClass {
public function someMethod($object) {
$object->doSomething();
}
}
Если normalClass::someMethod()
может быть вызван несколькими различными $object
s, это может быть лучший вариант (вместо того, чтобы предоставить $object
всему экземпляру normalClass).
Но независимо от этого вы можете подумать о создании интерфейса для использования для типа типа :
interface ISomethingDoer {
public function doSomething();
}
class normalClass {
public function someMethod(ISomethingDoer $object) {
# Now PHP will generate an error if an $object is passed
# to this function which does not implement the above interface.
// ...
class superClass implements ISomethingDoer {
// ...
Вы можете передать ссылку на первый объект следующим образом:
class normalClass {
protected $superObject;
public function __construct(superClass $obj) {
$this->superObject = $obj;
}
public function someMethod() {
//this method shall access the doSomething method from superClass
$this->superObject->doSomething();
}
}
class superClass {
public function __construct() {
//provide normalClass with a reference to ourself
$inst = new normalClass($this);
$inst->someMethod();
}
public function doSomething() {
//this method shall be be accessed by domeMethod form normalClass
}
}
woah У меня была такая же проблема, как у вас, но вместо того, чтобы идти с таким простым прохождением ссылки на объект, я пошел с менеджером событий. В принципе, когда что-то произойдет в нормальном классе, это вызовет событие, которое был прослушан классом и что упомянутый класс (слушатель) назвал суперкласс для выполнения этой функциональности и при необходимости передал ему новые аргументы.
В любом случае, передаете ли вы его в качестве параметра для своего объекта или используете подход, основанный на событиях, оба решения работают. Выберите тот, который вы предпочитаете.
Для получения дополнительной информации о событиях симпония объясняет это довольно неплохо. http://symfony.com/doc/current/components/event_dispatcher/introduction.html