本文主要是介绍程序员面试题之Static方法与普通方法有啥不同,静态方法可以不依赖于类的实例,可以直接通过类名调用,并可以访问和修改静态属性;普通方法需要通过类的实例对象调用,并可以访问和修改实例属性。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
AI:please wait…
在PHP中,静态方法(Static methods)与普通方法(Instance methods)有以下不同:
-
调用方式:静态方法可以通过类名直接调用,而普通方法需要通过类的实例对象调用。
示例:class MyClass {public static function staticMethod() {echo "This is a static method.";}public function instanceMethod() {echo "This is an instance method.";} }MyClass::staticMethod(); // 调用静态方法 $obj = new MyClass(); $obj->instanceMethod(); // 调用普通方法
-
访问权限:静态方法可以访问和修改静态属性(Static properties),而普通方法可以访问和修改实例属性(Instance properties)。
示例:class MyClass {public static $staticProperty = "Static Property";public $instanceProperty = "Instance Property";public static function staticMethod() {echo self::$staticProperty;}public function instanceMethod() {echo $this->instanceProperty;} }MyClass::staticMethod(); // 输出 "Static Property" $obj = new MyClass(); $obj->instanceMethod(); // 输出 "Instance Property"
-
继承:静态方法可以被继承并覆盖(Override),而普通方法也可以被继承并覆盖。
示例:class ParentClass {public static function staticMethod() {echo "This is the parent's static method.";}public function instanceMethod() {echo "This is the parent's instance method.";} }class ChildClass extends ParentClass {public static function staticMethod() {echo "This is the child's static method.";}public function instanceMethod() {echo "This is the child's instance method.";} }ParentClass::staticMethod(); // 输出 "This is the parent's static method." ChildClass::staticMethod(); // 输出 "This is the child's static method."$parentObj = new ParentClass(); $parentObj->instanceMethod(); // 输出 "This is the parent's instance method."$childObj = new ChildClass(); $childObj->instanceMethod(); // 输出 "This is the child's instance method."
https://www.php.net/manual/zh/language.oop5.static.php
声明类属性或方法为静态,就可以不实例化类而直接访问。
静态方法
<?php/*** 静态(static)关键字** 声明类属性或方法为静态,就可以不实例化类而直接访问。* 静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)** 由于静态方法不需要通过对象即可调用,所以伪变量$this在静态方法中不可用!!*/class Foo
{public static function aStaticMethod(){// ...echo '静态方法调用';}
}//两种静态方法的调用方式
Foo::aStaticMethod();
//$classname = 'Foo';
//$classname::aStaticMethod();
静态方法&&静态变量
<?php/*** 静态(static)关键字,静态属性** 静态属性不可以由对象通过 -> 操作符来访问。* 通过变量来引用一个类是可行的,但这个变量的值不能是一个保留字 (例如self,parent和 static)*/class Foo
{public static $my_static = '静态变量:foo';public function staticValue(){return self::$my_static;}
}class Bar extends Foo
{public function fooStatic(){return parent::$my_static;}
}print Foo::$my_static . "\n"; //直接调用静态变量//静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
$foo = new Foo();
print $foo->staticValue() . "\n"; //可以访问静态方法
//print $foo->my_static . "\n"; // 会报错的,静态属性不可以由对象通过 -> 操作符来访问。echo '<br/>';
echo '<br/>';
echo '<br/>';$foo = new Foo();
print $foo::$my_static . "\n";
$classname = 'Foo';
print $classname::$my_static . "\n";echo '<br/>';
echo '<br/>';
echo '<br/>';//Bar是子类访问父类的静态变量
print Bar::$my_static . "\n";
$bar = new Bar();
print $bar->fooStatic() . "\n";echo '<br/>';
print $bar->staticValue();
继承会覆盖
<?php/*** 继承会覆盖*/class A
{static protected $test = "class a";public function static_test(){echo static::$test; //打印什么?? class becho '<br/>';echo self::$test; //打印什么?? class a}
}class B extends A
{static protected $test = "class b";
}$obj = new B();
$obj->static_test();
静态成员由类的所有实例共享,尽管类的每个实例都存在一个非静态成员。
<?php/*** 也就是说,静态成员由类的所有实例共享,尽管类的每个实例都存在一个非静态成员。*/class Base
{public $a;public static $b;
}class Derived extends Base
{public function __construct(){$this->a = 0;parent::$b = 0;}public function f(){$this->a++;parent::$b++;}
}$obj1 = new Derived();
$obj2 = new Derived();
$obj3 = new Derived();$obj1->f();
echo $obj1->a;echo Derived::$b; //11echo '<br/>';
echo '<br/>';$obj2->f();
echo $obj2->a;echo Derived::$b; //12echo '<br/>';
echo '<br/>';$obj3->f();
echo $obj3->a;echo Derived::$b; //13
要检查类中声明的方法是否是静态的,可以使用以下代码。PHP5有一个反射类,非常有用
<?phpclass base
{public static function test(){}public function test1(){}
}try {$method = new ReflectionMethod('base::test');if ($method->isStatic()) {echo 'yes';} else {echo 'no';}
} catch (ReflectionException $e) {echo $e->getMessage();
}
修饰全局作用域的变量
<?phpfunction testStatic()
{static $val = 1; //修饰全局作用域的变量echo $val;$val++;
}/*** 在函数执行完后,变量值仍然保存*/
testStatic(); //echo 1
testStatic(); //echo 2
testStatic(); //echo 3
这里static的作用即类似于C里的static的作用,保证$a变量只有在add()第一次调用时才会被初始化,
但需要注意的是定义static变量的时候,可以不赋初值,可以给定初值,
但是赋初值的时候不能使用表达式或者调用函数赋值,否则会报错。
//www.kegog11.com/admin/demo/testpublic function test(){for($i=0;$i<5;$i++){static $a = 0;echo $a,"<br />";$a++;}echo $a,"<br />";}//结果集?
static变量不会存储引用(但是可以存储对象),
当static存储引用时,二次调用函数后,该变量的值并未被保存下来,
且运行上面程序会报Deprecated错误,即返回引用值赋值的用法已弃。
<?phpfunction get_obj_ref(){static $obj = null;echo '第一个:Ststic obj:';var_dump($obj);echo '<br/>';if(is_null($obj)){$obj = &new stdClass();}return $obj;
}
$obj = get_obj_ref();
$obj2 = get_obj_ref();//====================================================
echo '<br/>';function get_obj_noref(){static $obj = null;echo '第二个:Ststic obj:';var_dump($obj);echo '<br/>';if(is_null($obj)){$obj = new stdClass();}return $obj;
}
$obj = get_obj_noref();
$obj2 = get_obj_noref();
static在类中的延迟静态绑定;
/*** 2:static在类中的延迟静态绑定;** 延迟静态绑定是指允许在一个静态继承的上下文中引用被调用类。* 延迟绑定的意思为:* static::不再为定义当前方法所在的类,而是实际运行时所在的类。注:它可以用于(但不限于)静态方法的调用。** 除了简单的static延迟绑定的用法,还有一种转发调用,即使用self::,* parent::,static:: 以及forward_static_call()(该函数只能在方法中调用)将转发调用信息,如下:*/class A
{public static function foo(){static::who();}public static function who(){echo __CLASS__ . "\n";}
}class B extends A
{public static function test(){A::foo();parent::foo();self::foo();}public static function who(){echo __CLASS__ . "\n";}
}class C extends B
{public static function who(){echo __CLASS__ . "\n";}
}C::test();//这里得到的结果是A C C,显然在调用parent::foo()时,还是使用了运行时调用类。
还有一点需要注意的是:只有显示声明的static类才是从属与子类的。
<?php
/*** 还有一点需要注意的是:只有显示声明的static类才是从属与子类的。** 这里得到的结果是 b b。这里B类首先调用过test()方法,调用后$var2变量已经被赋值,* 而C类未定义自己的$var2变量,且父类中$var2变量值已经存在,* 故直接使用,若在B C类中显示定义$var2变量,则结果又会有所不同。*/class A
{protected static $var1 = null;protected static $var2 = null;public static function test(){if (!static::$var2) {static::$var2 = static::$var1;}echo get_called_class() . '===>' . static::$var2 . '<br/>';}
}class B extends A
{protected static $var1 = 'b';
}class C extends A
{protected static $var1 = 'c';
}B::test();
C::test();
这篇关于程序员面试题之Static方法与普通方法有啥不同,静态方法可以不依赖于类的实例,可以直接通过类名调用,并可以访问和修改静态属性;普通方法需要通过类的实例对象调用,并可以访问和修改实例属性。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!