创建对象的过程,就是类的实例化。
类必须实例化才能访问里面的属性和方法。
类的变量成员叫做“属性”,或者叫“字段”、“特征”,在本文档统一称为“属性”。属性声明是由关键字 public,protected 或者
private 开头,然后跟一个普通的变量声明来组成。属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指 PHP
脚本在编译阶段时就可以得到其值,而不依赖于运行时的信息才能求值。
属性的声明必须以访问控制符开头
public 公共属性,外部可以访问
private 私有属性,只允许类中的访问调用
protected 受保护的,仅允许本类或子类访问
属性支持 标量(整数、浮点、字符串、布尔值),复合类型:数组和对象
方法是类里的"函数",只能通过对象调用
方法也必须以访问控制符开头:public,private,protected
用对象访问运算符 ->
来直接访问属性,或执行方法
在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)
这种方式来访问非静态属性。$this
是伪变量,总是指向当前对象。
在类的外部访问属性或方法,可以直接用对象,在类的内部访问属性或方法,必须用$this
静态属性则是用 ::(双冒号):self::$property
来访问。
对象是一个引用变量,我们对对象的赋值并没有创建一个新变量,而是创建当前对象的引用
class Demo1{
public $name ='My name is Tom'
public function getName()
{
return $this->name;
}
public function getObj()
{
return new self();
}
public function getStatic()
{
return new static();
}
class Demo2 extends Demo1 //extends继承上个类
{
public function getNewObj()
{
return new parent();
}
}
1、用new类名()来创建一个对象
$obj = new Demo1();
echo $obj->name;
2、将类名,以字符串的方式放在一个变量中
$className = 'Demo1';
$obj1= new $className();
echo $obj1 ->name;
3、用对象来创建对象,并且它创建的是一个新对象
$obj2 = new $obj();
echo $obj2->name;
echo get_class($obj2);
4、new self()
$obj3 = $obj->getObj;
echo $obj3->name;
echo get_class($obj2);
5、用new parent()来创建对象
$obj4=(new Demo2)->getNewObj()
echo $obj4->name;
6、基于当前调用的类来创建 new static()
$obj5 = (new Demo1)->getStatic;
$obj6 = (new Demo1)->getObj();
// new static 创建的对象,直接与调用者绑定,静态延迟绑定
$obj7 = (new Demo2)->getStatic;
$obj8 = (new Demo2)->getObj();
在类中值始终不变的常量,用const创建,不加$符,必须初始化
内部访问
self::类常量名
外部访问
类名::类常量名
类变量::类常量名
对象::类常量名
构造方法:是用来实例化,创建对象的
__construct()
析构方法:用来销毁对象
__destruct()
class Staff //声明一个员工类
{
public $name;
public $age;
public $salary;
//构造方法使用的固定方法名:__construct()
public function __construct($name,$age,$salary)
{
//构造方法:通常是用来初始化对象中的属性
$this->name =$name;
$this->age =$age;
$this->salary=$salary;
}
//析构方法:对象销毁时自动调用,没有参数,__destruct()
public function __destruct()
{
echo '对象被销毁'
}
}
//创建一个对象,来访问类中的属性
$obj = new Staff('Peter',28,3500)
class Staff //声明一个员工类
{
private $name;
private $age;
private $salary;
//编写方法来访问对象的私有属性
public function getName()
{
return $this->name;
}
//使用魔术方法__get来直接从外部访问对象的私有属性
public function __get($a)
{
return $this->a;
}
//编写方法来设置对象的私有属性赋值
public function setName($name,$value)
{
$this->$name =$value;
}
//使用魔术方法__set来直接给私有属性赋值
public function __set($a,$value)
{
$this->$a =$value;
}
}
$obj = new Staff('Peter',28,3500)
echo $obj->getName();//使用编写的方法访问
echo $obj->age;//使用魔术方法直接访问对象的属性
echo $obj->salary;//使用魔术方法直接访问对象的属性
echo $obj->setName('name',Tom);//使用编写的方法设置对象属性
echo $obj->age = 45;//使用魔术方法直接设置不能访问的属性
echo $obj->salary= 8000;//使用魔术方法直接设置不能访问的属性
与此类似的魔术方法还有__construct(), __destruct(), __call(), __callStatic(),__get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state(), __clone() 和 __debugInfo()等方法。
extends 关键字
class 子类 extends 父类
创建子类是为了拓展父类的功能,实现代码复用
(今天有点懒了,复制粘贴一下菜鸟教程)
class BaseClass {
function __construct() {
print "BaseClass 类中构造方法" . PHP_EOL;
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct(); // 子类构造方法不能自动调用父类的构造方法
print "SubClass 类中构造方法" . PHP_EOL;
}
}
class OtherSubClass extends BaseClass {
// 继承 BaseClass 的构造方法
}
// 调用 BaseClass 构造方法
$obj = new BaseClass();
// 调用 BaseClass、SubClass 构造方法
$obj = new SubClass();
// 调用 BaseClass 构造方法
$obj = new OtherSubClass();
?>
PHP 不会在子类的构造方法中自动的调用父类的构造方法。要执行父类的构造方法,需要在子类的构造方法中调用 parent::__construct()
声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)
由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。静态属性不可以由对象通过 -> 操作符来访问。
访问控制符:指示类成员在哪里可以被访问:public/private/protected
成员状态符:指示如何访问该成员:静态self/parent/static 非静态:$this->
self::访问本类中的静态属性
parent::与父类进行静态绑定
static::与当前类的静态属性绑定,与前两者不同static对应的类是动态设置的,由调用类决定,如果说self和parent是静态绑定到类的话,static就是动态绑定到类,叫做静态延迟绑定(后期静态绑定)
静态绑定(self和parent)他们与类的绑定是在代码的编译阶段进行,而static与类的绑定是在代码的运行时才进行绑定,所以叫:静态延迟绑定(与类绑定的时机不同)
PHP 命名空间可以解决以下两类问题:
1.用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。
namespace MyProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
namespace AnotherProject;
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
?>
class Demo
{
public $name;
public $age;
public $salary;
private $sex;//私有属性
protected $isMarried;//受保护属性
public static $home;//静态属性
//声明构造方法,用来初始化属性
public function __construct($name,$age,$salary)
{
$this->name =$name;
$this->age =$age;
$this->salary=$salary;
$this->sex =$sex;
$this->isMarried =$isMarried;
self::$home =$home;
}
//声明一个query方法,用来在类的内部遍历属性
public function query()
{
print '遍历出对象中的全部属性,包括私有和受保护的:
';
foreach ($this as $key=>$value ){
print $key.'=>'.$value.'
';
}
print self::$home;
}
}
//外部访问
$obj = new Demo('peter',28,3800,'male',true,'shenyang');
//遍历对象
echo '外部访问公共属性:
';
foreach ($obj as $key => $value){
echo $key.'=>'.$value.'
';
}
echo Demo::$home;//外部使用类名访问静态成员
echo '
';
$obj->query();//遍历出对象中的全部属性