php类面向对象学习笔记

推荐《跟兄弟连学php》非常浅显易懂的一本php基础书籍,做个学习笔记新浪的博客实在没法用,转到csdn专业上来,最起码可以发代码
构造方法__construct()和构析方法​__destruct()

特殊的对象引用 $this 在对象的内部,对象的成员方法访问自己对象中的成员属性用$this

演示代码 http://127.0.0.1/everyday/class/person.php​​

<?php
class Person {
	var $name;
	var $sex;
	var $age;
	/*构造方法 创建对象是自动会调用*/
	function __construct($name='',$sex='男',$age=1) {
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}
	
	function say() {
		echo "名字:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
	}
	/*析构方法 在对象销毁前自动调用*/
	function __destruct() {
		echo "<br>已删除:".$this->name;
	}
}

$p1 = new Person('张明远','男',30);
$p1->say();
?>


魔术方法__set() __get() __isset() __unset()

实例演示 http://127.0.0.1/everyday/class/setget.php

<?php
class Person {
	private $name;//此属性被封装 私有
	private $sex;
	private $age;
	/*构造方法 创建对象是自动会调用*/
	function __construct($name='',$sex='男',$age=1) {
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}
	/*?__set() 在对象外部为private私有成员属性赋值会自动调用此方法,不能获取私有属性的值 声明魔术方法需要两个参数 
	  @parm string $name 成员属性名
	  @parm mixed $value 成员属性值
	*/
	function __set($name,$value) { //__set 设置为private 报错Warning: The magic method __set() must have public visibility and cannot be static
		if($name == 'sex') {
			if(!($value == '男' || $value == '女')) {
				return;//如果不是男或者女则返回中断
			}
		}
	
		if($name == 'age') {
			if($value > 150 || $value < 0) {
				return;//年龄超过150小于0返回中断
			}
		}
		
		$this->$name = $value;//注意 $this->$name 不是$this->name
	}
	
	/*__get() 在对象外部获取private私有属性的值时会自动调用此方法,一个参数 
	  @parm string $name 成员属性名
	  @return mixed $value 返回属性值
	*/
	 function __get($name) { //设置为private 是报错warning: The magic method __get() must have public visibility and cannot be static
		if($name == 'sex') {
			return "保密";
		} else if($name == 'age') {
			if($this->age > 120) {
				return $this->age-50;//年龄超过150减少50岁
			} else {
				return $this->age;
			}
		} else {
			return $this->$name;
		}		
	}
	
	/*
	  当在对象外面使用isset()函数测定私有成员属性时自动调用此函数
	  @parm string $name 成员属性名
	  @return boolean 返回真假
	*/
	function __isset($name) { 
		if($name == 'name') {
			return;//不允许测定name属性
		}	
		return isset($this->$name);		
	}
	
	/*
	  当在对象外面使用unset()函数删除私有成员属性时自动调用此函数
	  @parm string $name 成员属性名
	*/
	 function __unset($name) {
		if($name == 'name') {
			unset($this->$name);
		}		
	}
	
	function say() {
		echo "名字:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
	}

}

$p1 = new Person('张明远','男',30);
$p1->name = "赵子龙";
$p1->sex = "男";
$p1->age = 130;
$p1->say();
echo $p1->sex; //输出保密
echo $p1->age; //输出80
var_dump(isset($p1->name)); //不允许测定name属性 输出 boolean false
var_dump(isset($p1->sex));  //允许测定sex属性 输出 boolean teue
?>

继承中的方法重载演示,http://127.0.0.1/everyday/class/extends.php

<?php
class Person {
	protected $name;
	protected $sex;
	protected $age;

	function __construct($name='',$sex='男',$age=1) {
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}
	
	function say() {
		echo "名字:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
	}
}

class Student extends Person {
	private $school;
	
	function __construct($name='',$sex='男',$age=1,$school='') {
		parent::__construct($name='',$sex='男',$age=1);//重载父类中的构造方法,注意这里的参数可以不填也正常运行
		$this->school = $school;
	}
	
	function say() {
		parent::say();//重载父类中的say方法
		echo "我在".$this->school."上学";//在原有的功能上增加我在哪里上学功能
	}
}
$p1 = new Student('张明远','男',30,"北京大学");
$p1->say();
?>

常见的关键词:final static const 其他的魔术方法 __call() __toString() __autoload()

final:可以加在类和方法前,但不能使用final标识成员属性。并且标识的类不能被继承,标识的方法在子类中不能被覆盖。

static:可以用来标识类中的成员属性,也可以标识成员方法。因为静态成员是属于类的,不属于任何对象,所以不能用$this来引用他,需要用到self。

参看演示代码http://127.0.0.1/everyday/class/self.php

<?php
class Person {
	static $count;//声明一个静态成员属性,用来统计对象被创建的次数

	function __construct() {
		self::$count++;//创建一次对象就会自增1
	}
	
	static function getCount() {//声明一个静态方法,在类外不需要实例化对象就可以直接调用
		return self::$count;//在方法中使用self访问静态成员并返回
	}
}

Person::$count = 0;//在类外使用类名访问类中的静态成员,为其初始化赋值
$p1 = new Person();//创建一个对象自增1
$p2 = new Person();
$p3 = new Person();

echo Person::getCount();//在类外使用类名访问类中的静态方法,获取静态属性数值3
echo $p1->getCount();//通过对象也可以访问类中的静态成员方法,输出3
?>

单态设计模式:一个类只能有一个实例对象存在 http://127.0.0.1/everyday/class/dantai.php


<?php
class Db {
	private static $obj = null;
	/*private的构造方法只能在类内部实例化*/
	private function __construct() {
		echo "数据库连接成功";
	}
	
	static function getInstace() {
		if(is_null(self::$obj)) { //如果obj为null
			self::$obj = new self(); //实例化 在类中用 self() 或者直接使用类名 self::$obj = new Db();
		}
		return self::$obj; //返回实例化后的对象
	}
	
	function query() {
		echo "select name from user";
	}
}

$db = Db::getInstace(); //使用类名::调用static静态方法

$db -> query();
?>


const 、instanceof使用案例 http://127.0.0.1/everyday/class/const.php

<?php
class Person {
	const NAME = "狗蛋子"; //常量名通常大写
	
	function say() {
		echo self::NAME;//和static类似,在类中使用self访问
	}
}
echo Person::NAME;
$p1 = new Person();
$p1->say();
/*instanceof 判断一个对象是类的实例、类的子类*/
if($p1 instanceof Person) {
	echo "p1是person的实例化对象";
}
?>

clone 和__clone魔术方法的使用

<?php
class Person {
	var $name;
	var $sex;
	var $age;

	function __construct($name='',$sex='男',$age=1) {
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}
	
	function say() {
		echo "名字:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
	}
	/*魔术方法在对象克隆时自动调用,可以对属性重新赋值*/
	function __clone() {
		$this->name = "我是克隆人";
	}
}

$p1 = new Person('张明远','男',30);
$p2 = clone $p1; //克隆对象,并自动调用类中的魔术方法 __clone
$p1->say();
echo "<br>";
$p2->say();
?>

类中通用的方法 

__toString()  直接输出对象时自动调用,如果没有使用该魔术方法就会报错Catchable fatal error: Object of class Person could not be converted to string

__call 调用不存在的方法,自动调用魔术方法__Call

实例http://127.0.0.1/everyday/class/toString.php

<?php
class Person {
	var $name;
	var $sex;
	var $age;

	function __construct($name='',$sex='男',$age=1) {
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}

	/*直接输出对象时自动调用,如果没有使用该魔术方法就会报错Catchable fatal error: Object of class Person could not be converted to string*/
	function __toString() {
		return "<br>姓名:".$this->name;
	}
	
	function __Call($functionName,$args) {
		echo "<br>您调用的函数:".$functionName."不存在";
		print_r($args);
	}
}

$p1 = new Person('张明远','男',30);
echo $p1;//直接输出对象时自动调用__toString
$p1 -> ss(3,4);//调用不存在的方法,自动调用魔术方法__Call
?>

魔术方法__autoload 自动加载类:当对象被实例化时会自动调用该魔术方法 实例http://127.0.0.1/everyday/class/autoload.php

<?php
/*当对象被实例化时会自动调用该魔术方法*/
function __autoload($className) {
	include(strtolower($className).".php");
}


$p1 = new Person(); //当person类不存在时,自动调用__autoload
?>

对象串行化和反串行化,魔术方法__sleep() __wakeup() 实例http://127.0.0.1/everyday/class/serialize.php

<?php
class Person {
	var $name;
	var $sex;
	var $age;


	function __construct($name='',$sex='男',$age=1) {
		$this->name = $name;
		$this->sex = $sex;
		$this->age = $age;
	}
	
	function say() {
		echo "名字:".$this->name." 性别:".$this->sex." 年龄:".$this->age;
	}
	/*在对象串行化时自动调用,返回数组*/
	function __sleep() {
		$arr = array("name","age");//数组中的name age将被串行化,成员sex将被忽略
		return $arr;
	}
	/*在对象反串行化时自动调用,没有参数也没有返回值*/
	function __wakeup() {
		$this->age = 100;//反串行化时对age赋值
	}
}


$p1 = new Person('张明远','男',30);
$p1_string = serialize($p1);
echo $p1_string."<br>";


$p2 = unserialize($p1_string);
$p2->say();
?>


抽象类:用abstract修饰,是一种特殊的类,接口是一种特殊的抽象类。抽象类不能被实例化,只能被子类继承。

抽象方法:没有花括号用abstract修饰 例如 abstract function func1();

接口:用interface修饰类名,php中只支持单继承,而接口可以实现多继承,例如 class class_1 implements interface1,interface2,interface3 {}

多态性:php三大特性封装、继承、多态性;多态是指一段程序能够处理多种类型对象的能力;实例 http://127.0.0.1/everyday/class/duotai.php

<?php
/*声明一个USB接口*/
interface USB {
	function run();
}

class Computer {
	
	function useUSB($usb) {
		$usb-> run();
	}
	
}

class Ukey implements USB {//实现接口USB 接口不能用extends只能用implements
	
	function run() {
		echo "键盘插入了";
	}
}

class Umouse implements USB {//实现接口USB
	
	function run() {
		echo "鼠标插入了";
	}
}

$c = new Computer();
$c -> useUSB( new Ukey());//实例化键盘类
$c -> useUSB( new Umouse());//实例化鼠标类

?>


trait :php>5.4支持 用来混入类中使用,不能单独使用。为了减少单继承语言的限制,让开发人员能在不同层次结构内独立的类中复用方法集

<?php
/*trait php>5.4支持 用来混入类中使用,不能单独使用。为了减少单继承语言的限制,让开发人员能在不同层次结构内独立的类中复用方法集*/
trait trait1 {
	function func1() {
		echo 1;
	}
}
class class1 {
	use trait1;//声明一个类 在类中混入trait
}

$obj = new class1();
$obj -> func1();

?>

命名空间:解决重名问题;

案例:http://127.0.0.1/everyday/class/namespace.php

<?php
/*命名空间一个最明确的目的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产生一个致命的错误。这种情况下只要避免命名重复就可以解决,最常见的一种做法是约定一个前缀。*/
namespace hello;
use hello;
class hi{
	function a() {
		echo 'hi this a';
	}
}

namespace hello2;
use hello2 as h;//定义别名h
class hi {
	function b() {
		echo 'hi this b';
	}
}

$a = new \hello\hi();
$a->a();

$b = new h\hi();//使用别名h ,前面不需要再加\
$b->b();

?>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值