一、访问修饰限定符的概念
访问修饰限定符用于限定属性或方法可以被访问的位置,前面的public就是访问修饰限定符的一种。
public:公有,在类内和类外都可以访问。
protected:受保护,只可以在相关类内访问。
private:私有,只可以在当前类内访问。
私有存在的意义就是提供给类内方法访问,方法内的代码也属于类内,只可以在当前类的访问的属性或方法,一般都用在方法内。
属性必须有访问限定修饰符,方法可以不加,默认是public。
使用修饰限定符的步骤:
二、类内部对象
1.概念
$this是类内部对象,它是PHP提供的在类内部调用类属性和类方法的一个对象,他可以用在类方法内使用,并且只能在类结构内使用。
私有方法protected和private都是必须通过类内部对象访问,因为它们被限定无法在类外通过对象访问。
所有的公有方法不仅可以在类外通过对象访问,也可以在类内通过$this访问。
$this对象可以访问任意修饰符修饰的方法和属性(仅针对当前类)
因为类的内部访问属性和方法也需要对象,所以就有了$this对象。
将$this打印测试一下:
class MyTest{
private $name="Proking";
public function dump(){
var_dump($this);
}
}
$obj=new MyTest();
$obj->dump();
//object(MyTest)#1 (1) { ["name":"MyTest":private]=> string(7) "Proking" }
针对不同的类,$this的值是不同的。
class MyTest{
private $name="Proking";
public function dump(){
var_dump($this);
}
}
$obj=new MyTest();
$obj->dump();
class Abc{
public $age=18;
private $birthday=0420;
function dump(){
var_dump($this);
}
}
$A=new Abc();
$A->dump();
/*
针对MyTest类:
object(MyTest)#1 (1) { ["name":"MyTest":private]=> string(7) "Proking"
针对Abc类:
object(Abc)#2 (2) { ["age"]=> int(18) ["birthday":"Abc":private]=> int(272) }
*/
如何在类结构内访问类方法?
class Abc{
public $age=18;
private $birthday=0420;
function dump(){
global $A;
echo $A->age;
}
}
$A=new Abc();
$A->dump();
上面代码的原理是在类中调用已经实例化的对象,然后通过这个对象来访问类方法。
虽然 对象是在类外实例化的,但是最后访问还是在类内,所以即使是私有的属性也可以访问。
注意dump方法内有个global $A; 他代表接下来使用的$A 是全局变量而不是局部变量,如果不使用global关键字,$A是未定义的。
但是,这样做有个很大的弊端就是,在类结构外实例化的对象的名称被限制死了,如果我实例化的对象是$B,仍然会产生$A未定义的错误,而且某些情况我们可能会实例化不止一个对象,所以通过这个方法访问类内部的属性显然很鸡肋。
而$this 内部对象就能够很好地解决这个问题。
2.使用$this对象
$this对象可以在类的内部调用类的成员,如果我们需要在类中调用某个方法或者属性,就可以通过$this来实现:
class OrderBuy{
public $name="依维柯大金杯";
protected $price=8.88;
private $account=100;
public function order(){
//下单并扣除余额,返回剩余的余额
$this->account-=$this->price;
$str="你购买了:".$this->name.",支付:".$this->price."你的钱包还剩:".$this->account;
return $str;
}
public function dump(){
//调用下载操作,获取返回内容,打印输出。
$rs=$this->order();
echo $rs;
}
}
$CP=new OrderBuy();
$CP->dump();
//你购买了:依维柯大金杯,支付:8.88你的钱包还剩:91.12
这是一个简单的示例,很多情况下我们都需要在类内调用类内的成员,本例子中,最后只调用了dump方法就实现了下单,因为在类内的dump方法内就已经调用了order方法,如果不使用$this,还需要在类外调用一次order方法,并且order方法无法得知商品相关信息。不使用$this,这种简单的需求固然也是可以实现的,但是非常麻烦,并且要在类外产生大量代码,这就违背了面向对象编程的初衷:提高代码运行效率,节省代码量, 一次编写,处处调用,提高代码重复利用率。
3.原理
- class是定义类结构,属于非执行段代码,因此会被加载到代码段(编译阶段)
- new是实例化对象,先判定类在内存(代码段)是否存在
- 类不存在,报错;
- 类存在,将类内部的属性部分复制一份,然后在内存(堆区)开辟一块内存空间,将属性放到里面,同时内部有一个指针指向类的内存空间(代码段)
- 对象访问属性即访问的是对象空间里存储的部分
- 对象访问方法是对象通过内部指针找到类空间中的方法,然后在内存(栈区)开辟运行
- $this是系统在方法内置的对象通用名字
- 对象在调用方法的时候,系统会自动找到对象所保存的内存地址(堆区),然后把地址赋值给$this
- 方法内部的$this就代表调用当前$this所在方法的外部对象
- $this的本质是函数内部的一个局部变量,只是系统自动对其进行赋值,而且一定是调用方法的对象本身
- 面向对象编程代码运行内存关系:
Comments NOTHING