静态方法和实例方法的使用场景
1、从逻辑关系来看:(优先级2)
若方法与类的实例不存在逻辑上的联系,那么用静态方法。
反之则最好使用实例化方法。
2、从性能角度:(优先级3)
若方法经常被调用,则用静态方法更佳,因为这样可以避免频繁地实例化对象导致的资源占用,提高性能。
然而,由于静态的东西,在构造的时候是在堆中声称的,在结束之前不会被释放与改变,会一直占用内存空间,所以不宜有过多的静态成员。
因此若方法不会经常被调用,则使用实例方法可能会更好。
3、从线程并发的角度考虑:(优先级1)
要考虑方法是否存在严重的并发,
如果并发的可能性很大,则不适宜使用静态方法。
如果并发的可能性很小,或者通过简单的同步操作可以保证线程安全,那就可以考虑使用静态方法,这种情况下,静态方法要更快,更方便。
4、静态变量与普通变量的区别
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。
php 类的一些关键字
class myclass{
//命名空间
namespace common/api
//修饰关键字 进行方法和属性的封装;
/**public(公共的) private(私有的) protected(受保护的) ***/
public $name;
private $age;
protected $paw;
/***************************静态属性方法 关键字 static(静止的)*************************/
/**
*静态属性
*/
static $staticVal = 0;
/**
*静态方法
*/
static function changeStatic(){
echo self::$staticVal;
self::staticVal++;
return self::staticVal;
}
/***************************静态属性方法 关键字 static*************************/
/***************************构造方法关键字 __construct(建造) 析构方法关键字 __destruct(破坏)*************************/
//在创建时自动调用的方法; 与析构相反,析构是在对象销毁时自调用的方法
function __construct($name,$age){
$this->name = $name;
$this->age = $age;
}
function get($key){
return $this->$key;
}
function __destruct(){
echo '运行结束';
}
/***************************构造方法 关键字 __construct*************************/
}
静态属性调用
echo self::$staticVal;
######静态方法调用
myclass::changeStatic();
析构方法调用
$ages = new myclass('Tom',20);
echo $ages->get('age'); //输出结果 20 运行结束;
=========================分隔符==================================
全局变量关键字 global
global关键字用于函数内访问全局变量。
$x =5; //全局变量
$y=10; //全局变量
function myTest(){
global $x,$y;
$y=$x+$y;
echo $y; //15
}
继承关键字 extends
class pepper extends myclass{
}
通过继承实现多态用例
class animal{
function can{
echo '这是父类的使用方法';
}
}
class cat extends animal{
function can{
echo '我会喵喵喵';
}
}
class dog extends animal{
function can{
echo '我会汪汪叫';
}
}
function test($obj){
$boj->can();
}
test(new cat()); // 我会喵喵喵
test(new dog()); // 我会汪汪叫
__get(),__set()__isset(),__unset(),__empty() 魔术方法
// 获取对象属性时__get()被自动调用,一般用于获取私有属性 - 设置对象属性时__set()被自动调用 - isset判断是否存在该属性,empty相反 - 释放变量时__unset(),被自动调用
class Tomato {
private $name = "火星情报局";
public function __get($name){ //参数为属性名
if(isset($name)){ //isset判断是否存在该属性,与empty相反
echo "存在";
echo $this->name;
}else{
return null;
}
}
public function __set($name, $value){ //参数为 属性名、属性值
echo $this->$name = $value; //设置属性
}
public function __unset($name){ //释放属性变量时,被自动调用
echo "null";
}
}
$tomato->name; //获取元素属性
$tomato->name = "提莫队长"; //设置元素属性
unset($tomato->name); //释放变量
__call(),__callStatic() 魔术方法
__call()实现对方法的重载 __callStatic()实现对静态方法的重载 。implode()等价于spilt()方法
class Tomato {
public function __call($name, $arguments){
echo '$name:'.$name.'$arguments:'.implode(", ", $arguments);
}
public static function __callStatic($name, $arguments){
echo '$name:'.$name.'$arguments:'.implode(", ", $arguments);
}
}
$tomato->runSet("Allo", "Bllo"); //类内部没有该方法,是通过__call()重载实现的
Tomato::deRunSet("Cllo", "Dllo"); //类内部没有该静态方法,是通过__callStatic()重载实现的
__tostring(),__invoke
//__tostring()方法是在对象当作字符串输出时被自动调用 - __invoke()方法是在对象当作方法时被自动调用
class Tomato {
public function __tostring(){
return "string";
}
public function __invoke(){
echo "invoke";
}
}
$tomato = new Tomato();
echo $tomato; //对象当作字符串输出
$tomato(); //对象当作方法
__autoload
__autoload() 当加载了一个未定的类时触发
__autoload() 方法接收的一个参数,就是欲加载的类的类名,所以这时候需要类名与文件名对应,如 Person.php ,对应的类名就是 Pserson 。
Pserson.php
class Person {
private $name;
private $age;
function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
function say() {
echo "我的名字叫:".$this->name."
";
echo " 我的年龄是:".$this->age;
}
}
?>
test.php
function __autoload($class_name)
{
require_once $class_name.'.php';
}
//当前页面 Pserson 类不存在则自动调用 __autoload() 方法,传入参数 Person
$p1 = new Person("张三","20");
$p1 -> say();
?>
抽象类关键字 abstract(抽象的) 接口关键字 interface(接口)
抽象类和接口都是不能被实例化的特殊类。 可以在抽象类和接口中保留公共方法,将抽象类和接口作为公共的基类。
特性:抽象类中的抽象方法必须被子类实现(除非该子类也是抽象类),否则会报错。抽象类的中的非抽象方法可不被子类实现。子类只能继承一个抽象类,但可以继承多个接口
注意:抽象类必须至少包含一个抽象方法。抽象类中的方法不能被定义为私有 private,因为抽象类中的方法需要被子类覆盖。同样也不能用 final ,因为需要被子类继承。
abstract class class_name{
abstract public function fun_name(arg1,arg2);
abstract public function fun_name2(argg1,arg2,arg3);
}
接口关键字 interface
子类只能继承一个抽象类,但可以继承多个接口。接口实现了php 的多重继承。
interface database{
function connect($host,$username,$pwd,$db);
function query($sql);
function fetch();
function close();
function test();
}
interface MysqlAdmin{
function import();
function export();
}
接口继承 关键字implements
接口中的方法 必须被子类实现,并且不能包含实体
class mysqlNew implements database{
protected $conn;
protected $query;
function connect($host,$username,$pwd,$db){
$this->conn = new mysqli($host,$username,$pwd,$db);
}
function query(){
return $this->conn->query($sql);
}
function fetch(){
return $this->query->fetch();
}
function close {
$this->conn->close();
}
function test(){
echo 'test';
}
}
多接口继承
class mydb implements database,MysqlAdmin{
}
接口继承接口
interface Database extends MysqlAdmin{
function connect($host,$username,$pwd,$db);
function query($sql);
function fetch();
function close();
function test();
}
类中关键字
final 定义方法不被子类重写
final function demo(){
}
clone 克隆一个对象,克隆后的对象拥有原对象一切属性,并且不影响原对象。
class fate{
protected $name = "这是一只会飞的猪";
function test(){
echo 'test';
}
}
$obj = new fate();
$obj_clone = clone $obj;
$obj_clone -> name = '这是头牛';
echo $obj_clone->name;
__clone() 当对象被克隆时,执行该方法。
instanceof // 检测对象属于哪个类,以及实例是否继承某个接口