类的定义和实例化
<?php
// 类的定义使用class
class Demo{
// 定义属性
public $username="s0mf";
public $password="admin_s0mf";
// 定义方法
public function test(){
echo "This is test!";
}
}
// 类到对象实例化
$demo = new Demo();
// 对象中的成员属性可以用->来访问
echo $demo->username;
// 对象中的成员方法可以用->来访问
$demo->test();
代码运行:
s0mfThis is test!
构造函数
<?php
class Demo{
public $username="s0mf";
public $password="admin_s0mf";
// 默认的构造函数,在对象被实例化的时候自动调用
// 构造函数通常用于初始化对象的属性值
function __construct($username,$password){
echo "构造函数...";
// $this是php里面的伪变量,表示对象自身
// 通过$this可以设置对象的属性值
$this->username = $username;
$this->password = $password;
}
public function test(){
echo "This is test!";
}
}
$demo = new Demo("s0mf","admin_s0mf");
echo $demo->username."
";
echo $demo->password;
echo "<hr/>";
$demo2 = new Demo("admin","admin888");
echo $demo2->username."
";
echo $demo2->password;
代码运行:
构造函数...s0mf admin_s0mf
构造函数...admin admin888
析构函数
<?php
class Demo{
public $username="s0mf";
public $password="admin_s0mf";
function __construct($username,$password){
echo "构造函数...";
$this->username = $username;
$this->password = $password;
}
// 析构函数,用于清理程序中使用的系统资源,比如释放打开的文件等等
// 析构函数在该对象不会再被使用的情况下自动调用
function __destruct(){
echo "析构函数...";
print "Destroying " . $this->username . "
";
}
public function test(){
echo "This is test!";
}
}
$demo = new Demo("s0mf","admin_s0mf");
echo $demo->username."
";
echo $demo->password;
// 当对象变量被赋值为Null的时候,对象的析构函数会被自动调用
$demo = null;
echo "析构结束";
继承
<?php
/**
* 继承
* 1. 定义Human
* 2. 让Person继承Human
* 3. PHP中类不允许同时继承多个父类,也就是extends后面只能跟一个父类名称,这个特性被称为PHP的单继承特性
*/
class Human{
public $name;
public $sex;
public $age;
public function study($book){
echo $this->name."'s studying ".$book."
";
}
}
// extends关键字用于说明该类继承自某个父类
class Person extends Human{
public $e_mail;
function __construct($name, $sex, $age, $e_mail){
$this->name =$name;
$this->sex =$sex;
$this->age =$age;
$this->e_mail =$e_mail;
}
}
$person = new Person("s9mf", "男", "16", "s9mf@qq.com");
echo $person->e_mail."
";
$person->study("php");
/***
** 运行代码
** s9mf@qq.com s9mf's studying php
****/
访问控制
private protected public
本类内 Y Y Y
子类内 N Y Y
外部 N N Y
<?php
class Human{
private $name="陈先生";
protected $money = 4500;
public $age= 30;
public function say(){
echo '我叫',$this->name,'<br />';
echo '我每月用',$this->money,'<br />';
echo '我今年',$this->age,'岁<br />';
}
}
class Stu extends Human{
private $friend = '铁柱';
public function talk(){
echo '我叫',$this->name,'<br />';
echo '我每月用',$this->money,'<br />';
echo '我今年',$this->age,'岁<br />';
}
}
$ming = new Stu();
$ming->say(); // 都可以在本类内调用
$ming->talk(); // 不允许在子类调用private ,但是 protected,public允许
echo "<hr>";
echo $ming->age;
echo $ming->name; //出错 不允许在类外调用private
echo $ming->friend; //出错 不允许在子类调用private
echo $ming->money; // 出错 不允许在类外调用protected
代码运行:
我叫陈先生
我每月用4500
我今年30岁
我叫
Notice: Undefined property: Stu::$name in D:phpStudyPHPTutorialWWWphpdemo.php on line 17
我每月用4500
我今年30岁
30
Notice: Undefined property: Stu::$name in D:phpStudyPHPTutorialWWWphpdemo.php on line 27
Fatal error: Cannot access private property Stu::$friend in D:phpStudyPHPTutorialWWWphpdemo.php on line 28
Static(静态)关键字
<?php
class Human{
public $name;
public $sex;
public $age;
public static $test="这是父类成员属性";
public function study($book){
echo $this->name."'s studying ".$book."
";
}
}
class Person extends Human{
public $e_mail;
public static $teacher = "叶华";
public static function changeTeacher($newteacher){
// self或static用于表示当前类,"::"操作符用于访问类的静态成员
self::$teacher = $newteacher;
// parent用于表示父类,可以用于访问父类的静态成员
echo parent::$test . "
";
}
function __construct($name, $sex, $age, $e_mail){
$this->name =$name;
$this->sex =$sex;
$this->age =$age;
$this->e_mail =$e_mail;
}
}
// 类名加“::”可以访问类的静态成员
// 静态成员不需要实例化就可以访问
echo Person::$teacher;
Person::changeTeacher("谷哥");
echo Person::$teacher;
代码运行:
叶华这是父类成员属性 谷哥
重写与Final
<?php
/**
* 重写和Final
* 1. 子类中编写跟父类完全一致的方法可以完成对父类方法的重写
* 2. 对于不想被任何类继承的类可以在class之前添加final关键字
* 3. 对于不想被子类重写(overwrite, 修改)的方法,可以在方法定义前面添加final关键字
* 4.如果一个类被声明为 final,则不能被继承。final class B
* 5.属性不能被定义为 final,只有类和方法才能被定义为 final。
* 6.如果父类中的方法被声明为 final,则子类无法覆盖该方法
* 7.不在子类重写时,可以调用
*/
class B{
// final关键字 test()不能被重写
final public function test(){
echo "B::test called
";
}
public function test1(){
echo "B::test1 called
";
}
}
class A extends B{
// 父类test()方法的重写
// 重写时参数不一定要跟父类完全一致
public function test($tmp=0){
echo "A::test called
".$tmp;
}
}
$obj = new A();
$obj->test("tmp");
$obj->test1();
数据访问
<?php
/**
* 数据访问补充
* 1. parent关键字可以用于调用父类被重写的类成员
* 2. self关键字可以用于访问类自身的成员方法,也可以用于访问自身的静态成员和类常量;不能用于访问类自身的属性;访问类常量时不用在常量名称前面加$符号
* 3. static关键字用于访问类自身定义的静态成员,访问静态属性时需要在属性名前面添加$符号
*/
class B{
public function test(){
echo "B::test called
";
}
public function test1(){
echo "B::test1 called
";
}
}
class A extends B{
// 常量属性
const CONST_VALUE = 'A constant value';
private static $sValue = 'static value';
public function test($tmp=null){
echo "A::test called
".$tmp;
// parent可以访问父类中被子类重写的方法
parent::test();
self::called();
echo self::CONST_VALUE."
";
echo static::$sValue."
";
}
public function called(){
echo "A::called called
";
}
}
$obj = new A();
$obj->test();
接口
<?php
// interface用于定义接口
interface Read_book{
// 接口里面的方法不需要有方法的实现
public function read($book);
}
// implements用于表示类实现某个接口
class Human implements Read_book{
// 实现了某个接口之后,必须提供口中定义的方法的具体实现
public function read($book){
echo "Human reading ".$book."
";
}
}
class XiaoMing implements Read_book{
public function read($book){
echo "XiaoMing reading ".$book."
";
}
}
$obj = new Human();
$obj->read("<降龙十八掌>");
$xm = new XiaoMing();
$xm->read("<隔山打牛>");
// 不能实例化接口
// $read = new Read_book();
//
var_dump($obj instanceof Read_book);
function checkEat($obj){
if($obj instanceof Read_book){
$obj->read("葵花宝典");
}else{
echo "It's can't";
}
}
//同样的代码,传入接口的不同实现类的时候,表现不同。这就是为什么成为多态的原因。
checkEat($obj);
checkEat($xm);
// 可以用extends让接口继承接口
interface ICanPee extends Read_book{
public function pee();
}
// 当类实现接口时,父接口定义的方法也需要在这个类具体实现s
class Human1 implements ICanPee{
public function pee(){}
public function read($book){}
}
抽象类
<?php
/**
* 抽象类
* 1. 抽象类允许类里面的部分方法暂时没有具体实现,这些方法我们成为抽象方法
* 2. 一旦类里面有抽象方法,这个类就必须是抽象类
* 3. 抽象类跟接口一样,不能直接实例化为对象
*/
// abstract定义抽象类
abstract class ACanEat{
// 没有实现的方法需要设定为抽象方法
// 抽象方法需要在子类中实现
//这里定义的抽象方法。
abstract public function eat($food);
public function breath(){
echo "Breath use the air.
";
}
}
// Human类实现了ACanEat接口
class Human extends ACanEat{
public function eat($food){
echo "Human eating ".$food."
";
}
}
// Animal类实现了ACanEat接口
class Animal extends ACanEat{
public function eat($food){
echo "Animal eating ".$food."
";
}
}
$man = new Human();
$man->eat("Apple");
$man->breath(); // 和Animal共用了抽象类ACanEat的breath方法
$monkey = new Animal();
$monkey->eat("Banana");
$monkey->breath();
魔术方法
<?php
class MagicTest{
public function __tostring(){
return "This is the Class MagicTest ";
}
public function __invoke($x){
echo "__invoke called " . $x . "
";
}
}
$obj = new MagicTest();
echo $obj;
$obj("6");
__call 与 __callStatic
<?php
class MagicTest{
// 方法的重载
public function __call($name, $arguments){
echo "Calling ".$name."with parameters: ".implode(",", $arguments)."
";
}
// 静态方法的重载,注意这个方法需要设置成static
public static function __callStatic($name, $arguments){
echo "Static calling ".$name."with parameters: ".implode(",", $arguments)."
";
}
}
$obj = new MagicTest();
$obj->runTest("para1","para2");
echo "<hr>";
MagicTest::runTest("para1","para2");
<?php
class Human{
private function t(){
}
public function __call($name, $arg){
echo '你想调用不存在的方法 ',$name,'方法<br/>';
echo '还想传一个参数<br/>';
echo print_r($arg),'<br/>';
}
public static function __callStatic($name, $arg){
echo '你想调用不存在的方法 ',$name,'静态方法<br/>';
echo '还想传一个参数<br/>';
echo print_r($arg),'<br/>';
}
}
$obj = new Human();
$obj->t(1,2,3);
Human::s0mf("s0","mf");