PHP面向对象(OOP)

对象是放在“堆内存”里面, 对象的引用被放到了“栈内存”里,而静态成员则放到了“初始化静态段” 

自动加载类

__autoload(){}

会在使用尚未被定义的类的时候自动调用此函数,autoload函数接收一个参数,即需要引入的类名。

function __autoload($className){
   require_once $className.".php";
}
$obj=new MyClass(); //MyClass类不存在自动调用函数__autoload(),在实例化类的时候写__autoload()函数。此实例化时会传入参数“MyClass”。

此时不必将所需引入的类都一一 include进来。

对象串行化

串行化:serialize();  当某些对象需要在网络上传输,为了传输方便,可以将对象转为二进制串,当到达另一端时,再还原为原来的对象。

反串行化:unserialize();  把对象的二进制串再转为对象。

$p1=new Person('张三','男','20');
$p1_string=serialize($p1);
echo $p1_strubg;
$p2=unserialize($p1_string);

魔术方法:

__sleep():在串行化之前做一些操作(该方法不接受参数,但返回一个数组)

__wakeup():由二进制串重新组成新对象时,做一些对象醒来做的事。

function __sleep(){
   $arr=new array('name','sex'); //数组里是需要进行串行化的属性名
   return $arr;
}
function __wakeup(){
   $this->age='36';
}

接口interface

接口里的方法都是抽象方法,可以省略abstract关键字,默认都是抽象方法。接口中方法是空方法。 

接口里不能声明变量,只能声明常量(const )。

接口里所有的成员都是public权限的,也可省略不写,默认public。

接口是特殊的抽象类,里面所有的方法都是抽象方法,不能产生实例化对象,所有抽象方法需要子类去实现

子类实现接口中的抽象方法用implements,接口继承接口使用extends。

抽象方法

使用abstract关键字修饰,没有方法体,abstract function fun1();

抽象类

没有方法体。

只要类里有一个方法是抽象方法,这个类就要定义为抽象类,使用abstract关键字。

抽象类不能被实例化,只能被继承。

子类继承父类,子类必须实现父类全部的抽象方法,否则等于子类中包含抽象方法,子类也不能被实例化。

再通过实例化子类实现。

__call 处理调用错误

当调用的方法名错误或不存在调用的方法时,将执行该函数。

第一个参数:调用错误的方法名;

第二个参数:调用错误的方法时传的参数,以数组的形式传过来。

class Person{
  function __call($errFunName,$arrs){
      print('您调用的方法:'.$errFunName."(参数为:");
      print_r($arrs);
      print(')错误或不存在!');
    }
}

$p1=new Person();
$p1->run('1min','500m');
echo "Hello";  //当不存在__call方法时,如果调用不存在的方法,不会执行到此句。

克隆对象 clone

根据一个对象克隆出另一个一样的对象,克隆后两个对象互不干扰。

$p1=new Person('李木子','20','女');
$p2=clone $p1;
//使用clone克隆新对象p2,和p1对象具有相同的属性和方法。

在对象克隆时会自动调用"__clone"方法,该方法可以建立一个与原对象拥有相同属性和方法的对象。若想在克隆后改变原对象的内容,可以重写此方法。

"__clone"方法包含两个指针:$this指向复本,$that指向原本。

class Person{
   ...
   function say(){
     echo "我叫:".$this->name.",今年".$this->age."岁";
   } 
   function __clone(){
      $this->name="我是假的".$that->name;
      $this->age='100';
   }
}
$p1=new Person('张三','20','男');
$p2=clone $p1;
$p1->say();
$p2->say();

__toString() 输出对象引用时自动调用

$p1=new Person(); 此时$p1就是一个引用,此时如果输出“echo $p1;”会出错。

function __toString(){
  echo "您输出的是个引用";
}

static 

静态成员属于类,在类第一次被加载的时候分配的空间,其他类无法访问,只对类的实例共享。使用对象访问不到静态成员的。

从内存角度:对象是在堆内存中,对象的引用放在栈内存中。静态成员放在“初始化静态段”,在类第一次被加载的时候放入的,可以让堆内存里面的每个对象所共享。

访问静态方法:类名::方法名();  

访问静态属性:类名::$属性名;

或使用”self ::$attr;“。

self 是代表这个静态方法所在的类。

self表示当前类,即使该类类名被修改,仍可使用。

self是在类内调用静态成员的方式,而类名在类内和类外都可以调用。

一般来说,对象调用非静态方法,类用来调用静态方法

类里的静态方法只能访问静态属性(想在本类的方法中想访问本类的其他成员,需要使用$this这个引用,而静态方法不用对象调用的,而是使用类名来访问的 ,所以没有对象的存在,也就没有$this这个引用)

非静态方法可以访问静态属性,通过“self::成员属性名”

静态访问修饰符 “::”

const定义常量

也可使用define()函数

访问常量时通过类名,在方法里通过self,但是不使用$符号,也不能使用对象来访问。

访问:

类名::常量名(不加$符号)

self::常量名(不加$符号)

final关键字

使用final关键字标记的类不能被继承。

使用final关键字标记的方法不能被子类覆盖。

三种访问修饰符

public(公有的,默认的),private(私有的),protected(受保护的)

  private protected public
同一个类中  ok ok ok
类的子类中   ok ok
所有的外部成员     ok

方法重载

方法名相同,参数个数和参数类型不同

方法覆盖

子类继承父类,通过重写父类相同的方法名实现覆盖,重写父类的方法

想在父类方法的基础上进行扩展:

调用父类被覆盖的方法:

parent::方法名();

类名::方法名();

class children extends Person{
   ...
   function say(){
       //Person::say();
       parent::say();
       echo "在这可以加点功能";
   }
}

__set()

用来为私有成员属性设置值。有两个参数,第一个参数为设置的属性名,第二个参数为设置的属性值。

function __set($property_name,$value){
   $this->$proprty_name=$value;
}

__get()

用来获取私有成员属性的值。

function __get($property_name){
   if(isset($property_name)){
      return $property_name;
   }else{
      return NULL;
   }
}

isset()

传入一个变量作为参数,如果存在返回true,不存在返回false。

unset()

传入一个变量,删除指定的变量。

构造函数__construct()

使用new关键字来实例化对象的时候会自动调用构造方法,可以做一些初始化的工作,如为成员属性赋初值。

析构函数__destruct()

在销毁一个类之前执行一些操作。

$this

本对象的引用

$this->属性

$this->方法

使用对象的成员

对象成员包括成员属性和成员方法。通过“->”操作符访问

对象->属性

对象->方法

实例化对象

$对象名称 = new 类名称();

内存从逻辑上分为四段

栈空间段,堆空间段,代码段,初始化静态段

类是具有相同属性和服务的一组对象的集合。关键字class。

类和对象的关系

类与对象的关系就如磨具和铸件的关系。对象是类的实例化,类是对象的抽象。类是对某一类事物的抽象描述,对象用于表示现实中该类事物的个体,类用于描述多个对象的共同特征,它是对象的模板。对象用于描述现实中的个体,它是类的实例。

封装性

使用private对属性和方法进行封装。封装的成员不能被类外面之间访问,只有对象内部可以访问。将对象的属性和行为封装起来。

继承性

已存在的用来派生新类的类成为基类,又称为父类以及超类;由已存在的类派生出的新类称为派生类,又称子类。

通过继承,可以得到父类的方法和属性,也可以扩充自己,添加新的属性和方法。“可重用行”。

继承性主要描述的是类与类之间的关系。继承增强了代码的复用性,提高了程序开发效率。

多态

子类继承父类,重写(通过重写实现多态)父类的方法,方法名相同,参数类型和参数个数不同,实现不同的效果。同一操作作用于不同的对象,会产生不同的执行结果。

final关键字

不希望某个类被继承,只能被实例化。

当一个类被继承时,所包含的final方法不能被子类重写。

单例模式

一个类只能被实例化一次。

猜你喜欢

转载自blog.csdn.net/Lyj1010/article/details/82812043