머리말
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
합니다 .protected
public
정적 멤버 호출
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. 호출 private
및 protected
가시성 수준 의 정적 속성/방법
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->
개체를 통해서만 호출( 호출)할 수 있습니다. -
클래스의 모든 인스턴스 개체는 클래스의 정적 속성을 공유합니다. 이 클래스 정적 속성이 수정되면 이 클래스의 모든 개체가 이 새 값에 액세스할 수 있습니다.
-
정적 메서드 및 속성의 수명 주기는 해당 클래스만큼 길고 정적 메서드 및 정적 속성은 클래스 정의와 함께 메모리에 할당 및 로드됩니다. 정적 속성 및 메서드는 스레드가 끝날 때까지 소멸되지 않습니다. 비정적 메서드 및 속성의 수명 주기는 클래스의 인스턴스화된 객체만큼 길며, 클래스가 객체를 인스턴스화할 때만 비정적 메서드 및 속성이 생성되고 객체가 소멸되면 비정적 메서드 및 속성이 생성됩니다. 정적 메서드는 즉시 소멸됩니다. 정적 메서드와 정적 변수는 생성 후 항상 동일한 메모리 블록을 사용하는 반면 인스턴스를 사용하면 여러 메모리가 생성됩니다. 그러나 정적 메소드는 인스턴스화보다 효율적이며 정적 메소드의 단점은 자동으로 소멸되지 않는 반면 인스턴스화된 메소드는 소멸될 수 있다는 점입니다.
애플리케이션 시나리오:
-
정적 메서드는 파일 작업, 날짜 처리 메서드 등과 같은 도구 클래스의 메서드 정의에 가장 적합합니다.
-
정적 변수는 전역 변수의 정의에 적합합니다.
참조 링크:
PHP 정적 속성 및 정적 메소드 | 객체 지향 프로그래밍 | 실제 전투 튜토리얼에 대한 PHP 입문서
https://www.jb51.net/article/110708.htm