PHP面向对象入门(课内知识)+ 课外知识
PHP面向对象入门(课内知识)
类的申明与使用
//面向对象开发
//创建一个对象
Class demo1{
//对象里面的 方法与变量 叫做成员
//可以给成员赋值
public $name = 'Rain';
public function getName(){
return $this->name;
}
}
//如何访问 首先实例化对象
$demo = new demo1;
echo $demo->name;
echo $demo->getName();
是不是简简单单?好接下来开始提升一点点难度
self是谁?$this是谁?面向对象中内存使用原理(简单版)
首先我们要知道我们实例化对象的时候PHP对我们的内存干了些啥
$this是指所实例化对象所在的内存!
self是什么怎么用?
类的权限
- public 公共的
- protected 受保护的
- private 私有的
|
public |
protected |
private |
外部 |
Y |
N |
N |
内部 |
Y |
Y |
Y |
子类 |
Y |
Y |
N |
此案例中私有的没有输出说明它不允许在子类中被使用
构造方法 析构方法
//构造方法 析构方法
Class demo3{
//构造方法 __construct实例化类时优先执行 通常可以用来初始化
public function __construct($name='无名氏')
{
$this->name = $name;
}
public $name;
public function getName()
{
echo '名字是'.$this->name;
}
// 析构方法对象销毁时执行
public function __destruct()
{
echo '啊';
}
}
$ab = new demo3('小雨');
// echo $ab->name;
$ab->getName();
如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
class BaseClass {
function __construct() {
print "In BaseClass constructor\n";
}
}
class SubClass extends BaseClass {
function __construct() {
parent::__construct();
print "In SubClass constructor\n";
}
}
class OtherSubClass extends BaseClass {
// inherits BaseClass's constructor
}
// In BaseClass constructor
$obj = new BaseClass();
// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();
// In BaseClass constructor
$obj = new OtherSubClass();
类继承extends
+ parent::
子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被继承的方法都会保留其原有功能。
PS:extends就不单独列举说明这边讲一下parent::
class Demo6
{
public $site;
public function __construct($site='周小雨博客')
{
$this->site = $site;
}
public function getInfo(){
return $this->site;
}
}
class Demo7 extends Demo6
{
public $name;
public function __construct($name='小雨')
{
//我们这边因为是继承的并且没有写初始化site那么父类的构造方法不会执行所以我们手动启动一下
parent::__construct();
$this->name = $name;
}
//继承后我们将getInfo方法重写增加功能
public function getInfo()
{
//但是我们这里还想使用原先输出站点名称的功能我们就可以使用
return parent::getInfo() . '是' . $this->name . '的';
}
}
$pp = new Demo7();
echo $pp->getInfo();
PHP多类继承Trait(说白了代码复用..你可以理解为’变量’想在哪里用就哪里用)
trait Test
{
public function getInfo(){
return '我是'.$this->name.'是'.$this->site.'的站长';
}
}
Class Name
{
public $name;
public $site;
public function __construct($name,$site='周小雨博客')
{
$this->name = $name;
$this->site = $site;
}
use Test;
}
$xy = new Name('小雨');
echo $xy->getInfo();
//trait 不允许实例化 trait可以理解为把一堆代码打包了直接用use引用进去;
课外知识来了
如何实现一个单列模式
什么叫单列模式?就是对象只实例化一次!
我的思路是这样子的、
首先是创建一个类给他整一个随机数来看看咱实例化了几次
class Single
{
public $rand;
//来个构造方法
public function __construct(){
return $this->rand = mt_rand(1000,9999);
}
}
var_dump(new Single());
var_dump(new Single());
来看看一下是否能正常运行
那么接下来就是想一个办法只让对象实例化一次,那么就得想办法不然它在外部被调用那么我们改写一下
class Single
{
public $rand;
//来个构造方法
protected function __construct(){
return $this->rand = mt_rand(1000,9999);
}
}
var_dump(new Single());
var_dump(new Single());
好这样子就成功报错了!因为构造方法不允许被在外部被调用,所以实例化会出错。
那么下一步就是控制权转移使用静态成员
class Single
{
public $rand;
//来个构造方法
protected function __construct(){
return $this->rand = mt_rand(1000,9999);
}
//写一个控制器来控制构造方法想在不实例化中使用那就必须用静态成员
static public function getinfo()
{
return new Single();
}
}
var_dump(Single::getinfo());
var_dump(Single::getinfo());
OK这样子我们就成功转移了控制权
接下来我们只需要给控制加一个判断对象有无实例化即可
class Single
{
//搞一个静态成员flag
static public $flag = null;
public $rand;
//来个构造方法
protected function __construct(){
return $this->rand = mt_rand(1000,9999);
}
//写一个控制器来控制构造方法想在不实例化中使用那就必须用静态成员
static public function getinfo()
{
//判断flag是不是null
if(Single::$flag === null){
Single::$flag = new Single();
}
return Single::$flag;
}
}
var_dump(Single::getinfo());
var_dump(Single::getinfo());
以上就是完成一个单列模式的思路,只是我所理解的一种方法(不是最优秀的)方法很多,核心就是只让类实列化一次
Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:单例是有一定的使用场景限制的, 因为它违反了OOP原则,即代码复用, 但是对于一些特殊资源, 的确需要对类实例数量进行限制, 与其限制实例数量,还不如直接静态化, 不允许用实例,直接用类来得更彻底... 所以, 这是一个有争议的话题, 希望你能正确对待....