PHP 정적 정적 상세 설명

머리말

PHP 클래스 속성과 메서드는 클래스가 인스턴스화된 후에 호출해야 합니다.(상수 속성 제외) 그러나 PHP는 정적 속성과 정적 메서드도 제공합니다.소위 "정적"은 클래스를 인스턴스화하지 않고 직접 호출할 수 있음을 의미합니다. 이러한 속성 및 방법. 정적 클래스는 인스턴스화할 수 없지만 인스턴스화 없이 사용할 수 있습니다.

정적 멤버의 정의

static 키워드를 사용하여 클래스의 속성 및 메서드를 수정하고 이러한 속성 및 메서드를 정적 속성 및 정적 메서드라고 합니다.

1. 정적 속성

문법:

static 属性名

예:

<?php
class Foo {
  public static $my_static = 'hello';  
}
?>

2. 정적 방법

문법:

static function 方法名{
    //代码
}

예:

<?php
class Foo {
  public static function staticValue() {
     return 'hello';
  }
}
?>

참고: 개체 속성 및 메서드와 같은 정적 속성 및 메서드는 , , 세 가지 가시성 수준 설정을 지원 private합니다 .protectedpublic

정적 멤버 호출

1. 클래스 외부에서 정적 속성/메소드 호출

类名::属性/方法 에 의해 호출되었습니다.

<?php
class Mystatic {
  public static $staticvalue = 'zhangsan';
  public static function staticMethod() {
    $a = 'hello';
    return $a;
  }
}
echo '$staticvalue: '.Mystatic::$staticvalue.PHP_EOL;
echo '$a: '.Mystatic::staticMethod().PHP_EOL;
?>

참고: 미리 정의된 상수는 시스템 개행 문자를 PHP_EOL나타냅니다 .

결과:

$staticvalue: zhangsan
$a: hello

对象名::属性/方法 에 의해 호출되었습니다.

<?php
class Mystatic {
  public static $staticvalue = 'zhangsan';
  public static function staticMethod() {
    $a = 'hello';
    return $a;
  }
}
$obj = new Mystatic();
echo '$staticvalue: '.$obj::$staticvalue.PHP_EOL;
echo '$a: '.$obj::staticMethod();
?>

결과:

$staticvalue: zhangsan
$a: hello

对象名 -> 方法호출 하면 对象名 -> 属性실패합니다.

<?php
error_reporting(0);
class Mystatic {
  public static $staticvalue = 'zhangsan';
  public static function staticMethod() {
    $a = 'hello';
    return $a;
  }
}
$obj = new Mystatic();
echo '$staticvalue: '.$obj -> staticvalue.PHP_EOL;
echo '$a: '.$obj -> staticMethod();
?>

결과:

$staticvalue:
$a: hello

2. 비정적 메서드에서 정적 속성/메소드 호출

에 의해 호출 되는 self는 $this가 현재 객체를 가리키는 것처럼 현재 클래스를 가리키고 , 인스턴스화가 없는 경우 포인터는 빈 객체를 가리키 므로 정적 속성 및 메서드를 참조하기 위해 건드릴 수 없습니다. self::属性/方法$this

<?php
class Mystatic {
  public static $staticvalue = 'zhangsan';
  public static function staticMethod() {
    $a = 'hello';
    return $a;
  }
  public function noStatic(){
    echo '$staticvalue: '.self::$staticvalue.PHP_EOL;
    echo '$a: '.self::staticMethod();

  }
}
$obj = new Mystatic();
$obj -> noStatic();
?>

결과:

$staticvalue: zhangsan
$a: hello

3. 정적 메서드에서 정적 속성/메서드 호출

비정적 메서드에서 정적 속성/메소드를 호출하는 것과 동일합니다.

<?php
class Mystatic {
  public static $staticvalue = 'zhangsan';
  public static function staticMethod1() {
    $a = 'hello';
    return $a;
  }
  public static function staticMethod2(){
    echo '$staticvalue: '.self::$staticvalue.PHP_EOL;
    echo '$a: '.self::staticMethod1().PHP_EOL;

  }
}
Mystatic::staticMethod2();
$obj = new Mystatic();
$obj -> staticMethod2();
?>

결과:

$staticvalue: zhangsan
$a: hello
$staticvalue: zhangsan
$a: hello

4. 다른 클래스의 정적 속성/메소드 호출

클래스에서 다른 클래스의 정적 속성 및 메서드를 호출하는 경우 이를 참조해야 합니다. 完整类名::

<?php
class Mystatic1 {
  public static $staticvalue1 = 'xiaomin';
}
class Mystatic2 {
  public static $staticvalue2 = 'zhangsan';
  public static function staticMethod() {
    echo '$staticvalue1: '.Mystatic1::$staticvalue1.PHP_EOL;
    echo '$staticvalue2: '.self::$staticvalue2.PHP_EOL;

  }
}
Mystatic2::staticMethod();
$obj = new Mystatic2();
$obj -> staticMethod();
?>

결과:

$staticvalue1: xiaomin
$staticvalue2: zhangsan
$staticvalue1: xiaomin
$staticvalue2: zhangsan

5. 호출 privateprotected가시성 수준 의 정적 속성/방법

private속성의 제한 으로 인해 protected클래스 내에서만 호출이 가능하며, 클래스 외부에서 호출하려면 메소드 public, 메소드 접근 private, protected속성을 외부에 제공해야 합니다. 용어: 클래스는 외부 세계에 대한 인터페이스를 제공합니다.

<?php
class Mystatic {
  public static $staticvalue1 = 'zhangsan';
  private static $staticvalue2 = 20;
  protected static $staticvalue3 = 'student';
  private static function staticMethod() {
    $a = 'hello';
    return $a;
  }
  public function port1() {
    echo '$staticvalue1: '.self::$staticvalue1.PHP_EOL;
    echo '$staticvalue2: '.self::$staticvalue2.PHP_EOL;
    echo '$staticvalue3: '.self::$staticvalue3.PHP_EOL;
    echo '$a: '.self::staticMethod().PHP_EOL;
  }
  public static function port2() {
    echo '$staticvalue1: '.self::$staticvalue1.PHP_EOL;
    echo '$staticvalue2: '.self::$staticvalue2.PHP_EOL;
    echo '$staticvalue3: '.self::$staticvalue3.PHP_EOL;
    echo '$a: '.self::staticMethod().PHP_EOL;
  }
}
$obj = new Mystatic();
$obj -> port1();
echo "\r\n";
Mystatic::port2();
?>

결과:

$staticvalue1: zhangsan
$staticvalue2: 20
$staticvalue3: student
$a: hello

$staticvalue1: zhangsan
$staticvalue2: 20
$staticvalue3: student
$a: hello

정적 속성은 동적 수정을 지원합니다.

실제 응용 프로그램에는 데이터 조각을 공유할 수 있는 클래스의 여러 개체가 있습니다. 클래스 상수와 정적 속성을 모두 구현할 수 있습니다. 정적 속성은 클래스 상수와 유사(동일)하지만 유일한 차이점은 클래스 상수는 변경할 수 없지만 정적 속성은 변경할 수 있다는 것입니다. 액세스 방법은 동일하며 둘 다 ::액세스를 사용할 수 있습니다. 정적 속성은 $를 추가해야 하며 상수 이름 앞에 $가 없으므로 클래스 상수에 액세스할 때 추가할 필요가 없습니다.

1. 클래스 상수

<?php
class Myconst {
  const A = 1234;
}
$obj1 = new Myconst();
echo 'A: '.$obj1::A.PHP_EOL;
$obj1->A='aaa';
//$obj1::A='aaa';会报错
echo "\r\n";
$obj2 = new Myconst();
echo 'A: '.$obj2::A.PHP_EOL;
?>

결과:

A: 1234

A: 1234

2. 정적 속성

<?php
class Mystatic {
  public static $A = 1234;
}
echo '$A: '.Mystatic::$A.PHP_EOL;
Mystatic::$A = 6666;
echo '$A: '.Mystatic::$A.PHP_EOL;
$obj1 = new Mystatic();
echo '$A: '.$obj1::$A.PHP_EOL;
Mystatic::$A = 5555;
$obj2 = new Mystatic();
echo '$A: '.$obj2::$A.PHP_EOL;
echo '$A: '.$obj1::$A.PHP_EOL;
?>

결과:

$A: 1234
$A: 6666
$A: 6666
$A: 5555
$A: 5555

정적 멤버의 상속 및 재정의

비정적 속성/메서드와 마찬가지로 정적 속성 및 메서드도 하위 클래스에서 상속할 수 있으며 정적 속성 및 메서드도 하위 클래스에서 재정의할 수 있습니다.

1. 정적 속성

하위 클래스는 상위 클래스의 정적 멤버 변수를 다시 작성할 수 있지만 상위 클래스의 정적 변수는 여전히 존재합니다.이 두 정적 멤버 변수는 독립적이며 호출 클래스 이름에 따라 별도로 액세스됩니다.

<?php
class Mystatic
{
    static public $a;           //定义一个静态变量
    static function test()        //定义静态方法来操作并输出静态变量
    {
        self::$a++;
        return self::$a;
    }
}
class Mystatic2 extends  Mystatic          //定义一个子类
{
    static function test()           //定义子类的静态方法
    {
        self::$a++;                 //访问并操作父类的静态变量
        return self::$a;
    }
}
$obj1=new Mystatic;                              //新建父类对象
echo '此时$a的值为: '.$obj1->test().PHP_EOL;     //通过对象调用静态方法test,静态属性$a的值+1
$obj2=new Mystatic;                              //新建另一个父类对象
echo '此时$a的值为: '.$obj2->test().PHP_EOL;     //新父类对象调用静态方法test,静态属性$a的值+1+1
$obj3=new Mystatic2;                             //新建子类对象
echo '此时$a的值为: '.$obj3->test().PHP_EOL;     //子类对象调用同名静态方法test, 静态属性$a的值+1+1+1
echo Mystatic::$a.PHP_EOL;    //通过父类::直接访问静态成员$a变量
echo $obj1::$a.PHP_EOL;   //通过对象名::可以直接访问静态成员$a变量
?>

결과:

此时$a的值为: 1
此时$a的值为: 2
此时$a的值为: 3
3
3

2. 정적 방법

하위 클래스는 상위 클래스의 정적 메서드를 재정의할 수 있습니다.

<?php
class Mystatic1 {
    public static function getclassName() {
        return __CLASS__;
    }

    public static function whoclassName() {
        echo self::getclassName().PHP_EOL;
    }
}

class Mystatic2 extends Mystatic1{
    public static function getclassName() {
        return __CLASS__;
    }
}

echo Mystatic1::getclassName().PHP_EOL;
echo Mystatic2::getclassName().PHP_EOL;
?>

현재 클래스의 클래스 이름은 를 통해 얻을 __CLASS__수 있으며 getClassName두 클래스의 메서드를 각각 호출합니다.

결과:

Mystatic1
Mystatic2

하위 클래스가 부모 클래스의 동일한 이름으로 정적 메서드를 재정의하고 하위 클래스에서 부모 클래스의 whoclassName메서드를

<?php
class Mystatic1 {
    public static function getclassName() {
        return __CLASS__;
    }

    public static function whoclassName() {
        echo self::getclassName().PHP_EOL;
    }
}

class Mystatic2 extends Mystatic1{
    public static function getclassName() {
        return __CLASS__;
    }
}

echo Mystatic1::whoclassName();
echo Mystatic2::whoclassName();
?>

결과:

Mystatic1
Mystatic1

두 번째 인쇄 결과가 하위 클래스 Mystatic1이름 Mystatic2? 이는 포인터가 항상 $this자신을 담고 있는 참조 객체를 가리 키지 self.定义时持有它的类调用时的类

게으른 정적 바인딩

Late Static Bindings(Late Static Bindings)는 정적 메서드의 호출을 목적 으로 하며, 이 기능을 사용할 때 더 이상 정적 메서드를 를 통해 self:: 참조 . 시간, 그것은 함수 하위 클래스 또는 다른 클래스에서 호출되면 그것을 가리 킵니다 . static::指向当前类self调用该方法所在的类

<?php
class Mystatic1 {
    public static function getclassName() {
        return __CLASS__;
    }

    public static function whoclassName() {
        echo static::getclassName().PHP_EOL;
    }
}

class Mystatic2 extends Mystatic1{
    //self改为static
    public static function getclassName() {
        return __CLASS__;
    }
}
echo Mystatic1::whoclassName();
echo Mystatic2::whoclassName();
?>

결과:

Mystatic1
Mystatic2

늦은 정적 바인딩이 적용됨을 나타냅니다. 즉, 정의될 때가 아니라 호출하는 메서드가 있는 클래스를 static가리키 므로 지연된 정적 바인딩이라고 합니다.

또한 를 사용하여 현재 호출 클래스의 클래스 이름을 static::class가리킬 . 예를 들어 __CLASS__위의 하위 클래스가 getClassName메서드를 대신 사용할 수 있습니다.

<?php
class Mystatic1 {
    public static function getclassName() {
        return static::class;
    }

    public static function whoclassName() {
        echo static::getclassName().PHP_EOL;
    }
}

class Mystatic2 extends Mystatic1{}

echo Mystatic1::getclassName().PHP_EOL;
echo Mystatic2::getclassName().PHP_EOL;
echo Mystatic1::whoclassName();
echo Mystatic2::whoclassName();
?>

결과:

Mystatic1
Mystatic2
Mystatic1
Mystatic2

같은 방식으로 self::class항상 자신을 정의하는 클래스를 가리킵니다.

정적과 비정적의 차이점

  • 정적 속성 및 메서드는 클래스에서 직접 참조할 수 있으므로 클래스 속성 및 클래스 메서드라고도 합니다. 비정적 속성 및 비정적 메서드는 인스턴스화 후 개체에서 참조해야 하므로 개체 속성 및 개체 메서드라고 합니다.

  • 정적 속성은 클래스 공간에 저장되고 비정적 속성은 오브젝트 공간에 저장됩니다. 비정적 메서드는 클래스의 모든 멤버(정적 포함)에 액세스할 수 있으며 정적 메서드는 클래스의 정적 멤버에만 액세스할 수 있습니다.

  • 정적 메서드는 클래스 이름 호출 및 개체 호출( 호출)과 같이 직접 호출할 수 类名或self::있지만 비정적 메서드는 对象名或$this->개체를 통해서만 호출( 호출)할 수 있습니다.

  • 클래스의 모든 인스턴스 개체는 클래스의 정적 속성을 공유합니다. 이 클래스 정적 속성이 수정되면 이 클래스의 모든 개체가 이 새 값에 액세스할 수 있습니다.

  • 정적 메서드 및 속성의 수명 주기는 해당 클래스만큼 길고 정적 메서드 및 정적 속성은 클래스 정의와 함께 메모리에 할당 및 로드됩니다. 정적 속성 및 메서드는 스레드가 끝날 때까지 소멸되지 않습니다. 비정적 메서드 및 속성의 수명 주기는 클래스의 인스턴스화된 객체만큼 길며, 클래스가 객체를 인스턴스화할 때만 비정적 메서드 및 속성이 생성되고 객체가 소멸되면 비정적 메서드 및 속성이 생성됩니다. 정적 메서드는 즉시 소멸됩니다. 정적 메서드와 정적 변수는 생성 후 항상 동일한 메모리 블록을 사용하는 반면 인스턴스를 사용하면 여러 메모리가 생성됩니다. 그러나 정적 메소드는 인스턴스화보다 효율적이며 정적 메소드의 단점은 자동으로 소멸되지 않는 반면 인스턴스화된 메소드는 소멸될 수 있다는 점입니다.

애플리케이션 시나리오:

  1. 정적 메서드는 파일 작업, 날짜 처리 메서드 등과 같은 도구 클래스의 메서드 정의에 가장 적합합니다.

  2. 정적 변수는 전역 변수의 정의에 적합합니다.

참조 링크:

PHP 정적 속성 및 정적 메소드 | 객체 지향 프로그래밍 | 실제 전투 튜토리얼에 대한 PHP 입문서

https://www.jb51.net/article/110708.htm

PHP 클래스의 비밀 (4) 정적 속성 및 정적 메서드 - 너겟

정적 메소드와 비정적 메소드의 차이점 - kittyUncle - 博客园

추천

출처blog.csdn.net/WHQ556677/article/details/122356593