<?php
use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Compare;
/**
* 访问控制
* public 公有
* private 私有 只能在类内部使用
* protected
* 类的属性和方法
* this 类的一个实例
* 类常量
* ----继承----
* 当父类的方法是私有的private的时候,子类是不能调用的,内部是可以访问的
* 当父类的方法是受保护的protected的时候,子类是可以访问的
* 当子类的方法与父类的方法相同的时候, 子类覆盖父类方法
* 当子类没有构造方法时, 直接调用父类的构造方法
* 当子类和父类都有构造方法时, 子类调用其本身的构造方法,当想调用父类的构造方法时使用:parent::construct();
* ---final 关键字---
* final class Dad {} 类加上final 关键字后, 类不能被继承
* final function Name(){} 父类的方法加上final关键字后,该方法在子类时不能被重写的
* --- 命名空间---
* namespace venter\session
* namespace test
* ---define----
* define 定义常量是全局的
* --- const 定义常量----
* ---自动加载类 autoload 用的少 基本都在使用 spl_autoload_register()----
* ---static 关键字---
* 当属性和方法被定义为static的时候, 这个属性和方法就属于类的属性和方法, 可以直接调用, 不需要实例化
* ----对象复制---
* 在php中对象的拷贝是浅拷贝, 改变地址
*
* --- 接口---
* 接口是类的模板,类是对象的模板
* interface Person{
* }
*
**/
class Computer{
//属性
public $cpu=5000;
public $mainboard ='huashuo';
private $ht="512";
const ONE =1;
const TWO= self::ONE+1;
const THREE = self::TWO+1;
//构造方法 实例化的时候调用
public function __construct()
{
}
function __autoload($name){
require $name.".php";
}
//方法
public function game($gamename){
if($this->hdSize<1024){
echo '内存太小';
return false;
}
return true;
}
public function job($jobName='write code'){
$this->game("ddd");
}
public function hdSize(){
$this->ht;
}
//析构方法
public function __destruct()
{
}
}
// var_dump(Computer::THREE);
// $computer = new Computer();
// $computer->job();
class Person{
public static $hand ="手";
public static $foot = "脚";
static function getCount(){
return self::$foot;
}
}
echo Person::getCount();
class A{
public static function who(){
echo "A类的方法";
}
public static function test(){
//self::who() ; //父类本身的who方法
static::who(); // static 自动判断,是类A还是类B, 后期绑定
}
}
class B extends A{
public static function who(){
echo "B类的方法";
}
}
echo B::test(); // 此时输出 “B类的方法”
class Test{
private $abc="";
public $testi;
public function __set($var,$val){
$this->var=$val;
}
public function __get($var){
return $this->var;
}
//调用的方法不存在时, 不会报错 两个参数, 一个方法名, 一个参数名
public function __call($func,$var){
var_dump($var) ;
}
//静态方法未定时,调用不会报错 $test::goes("r","d","4");
public static function __callStatic($name, $arguments)
{
var_dump($arguments);
}
public function __toString(){
return $this->test;
}
}
$test = new Test();
$test->abc ='abcsss';
$test->go("q","d","dd"); //已数组的方式传参数 go方法没有定义,不会报错
$test::goes("r","d","4"); // 该方法未定义直接调用, 不会报错,
echo $test; //echo 输出对象不会报错, 因为定义了 __toString()魔术方法
var_dump($test->abc);
//接口-----------------------------------------------------------
interface Persons{
public function eat();
public function sleep();
}
class Woman implements Persons{
public function eat(){
echo "eat fruit";
}
public function sleep(){
echo 'sleep early';
}
}
class Man implements Persons{
public function eat(){
echo "eat fruit less";
}
public function sleep(){
echo 'stay up';
}
}
class L {
public static function factory(Persons $user){
return $user;
}
}
$result = L::factory(new Man());
$result->eat();
$result->sleep();
//接口 继承--------------------------------------------------------------------------
interface ai{
const abc="hhhh";
public function a();
}
interface bi{
public function b();
}
interface ab extends ai,bi{
}
class Test4 implements ab{
public function a(){
echo "aaaaaaaaa";
}
public function b(){
echo "bbbbbbb";
}
}
$dd = new Test4();
$dd->a();
$dd->b();
echo (ai::abc);
// 抽象类abstract、
abstract class ABC {
public function holiday(){
echo "wait";
}
public function sleep(){
}
public function eat(){
}
}
class ABB extends ABC{
public function sleep(){
echo "Yes";
}
public function eat(){
$this->holiday();
echo "No";
}
}
$aaa = new ABB();
$aaa->eat();
$aaa->sleep();
//------单例模式和工厂模式----------
//单例模式确保类只能有一个实例 节省空间
class TestAB{
private static $_instance =null;
private function __construct()
{
}
private function __clone(){
}
public static function getInstance(){
if(!(self::$_instance instanceof self)){
self::$_instance =new self();
}
return self::$_instance;
}
}
$nn = TestAB::getInstance();//实例化两次,但是只开辟一次空间 两个变量值相同
$nn2 = TestAB::getInstance();
print_r($nn) ;
print_r($nn2) ;
//------- 工厂模式
//
class Memcache{
public function set(){
}
public function get(){
}
public function delete(){
}
}
class Cache{
public static function factory(){
// 文档中多数运用Memcache类时, 假如因为当前需要,改为redis ,需要使用工厂模式
return new Memcache();
}
}
//直接把Memcache 替换为redis 即可, 其他代码部分不需要更改
$cache = cache::factory();
$cache->set();
实现工厂模式:在定义多个功能类似的类,可以加一个工厂类,在这个工厂类里只返回实例化的后的类,然后切换底层的功能就只能修改工厂类了;
比如memcache和redis驱动,可以定义一个Cache类来作为工厂类来实现缓存切换;
要实现单例首先要将__construct和__clone方法私有化,然后定义个获取实例的静态方法,使用instanceof来判断实例化的对象是否属于当前对象,如果属于则直接返回,不属于则new一个;
单例模式的好处可以减少内存开销;
抽象类跟接口差不多,都可以定义空方法,但是接口里面定义的方法不能实现具体功能,只能定义空方法(不能写具体的代码),而抽象类可以定义空方法,也可以实现方法的具体功能(可以写具体的代码);
面向对象编程其实也是面向接口编程,使用接口来设计功能会使代码松耦合,设计功能的时候尽量使用接口来设计功能。
接口是不能被实例化的;
接口之间可以继承;
工厂模式:负责用来创建类的实例
单例模式:确保一个类只有一个实例
抽象类(abstract):区别于接口 interface 在于,里面可以包含具体的方法
接口 interface:定义空的方法,然后其他类来实现方法的具体操作
接口不能被直接实例化
接口可以继承
接口可以使用常量
单例模式例子
单例模式
public static function getInstance()
{
if(!(self::$_instance instanceof of self)){
self::$_insance = new self();
}
return self::$_instance;
}
判断 $_instance 是否为 当前类的事例
抽象类中可以有部分函数的具体实现, 但接口不可以
interface Ia
interface Ib
interface AB extends Ia, Ib - 继承
class Test implements AB - 实现
<?php
class test1{
public static function __callStatic($model,$arga)
{
echo $model."<br />";
print_r($arga);
}
}
test1::go(1,'ok');
echo "<hr />";
class A{
public function go()
{
echo 'gogogogog....';
}
}
function test(A $a)
{
$a->go();
}
test(new A());
echo "<hr /> 单例模式:";
class Test{
private static $_instance = null;
private function __construct()
{
}
private function __clone()
{
}
public static function getInstance()
{
if(!(self::$_instance instanceof self)){
self::$_instance = new self();
}
return self::$_instance;
}
}
$test1 = Test::getInstance();
$test2 = Test::getInstance();
$test3 = Test::getInstance();
var_dump($test1);
var_dump($test2);
var_dump($test3);
echo "<hr /> 工厂模式:便于底层类的批量修改";
class Redis
{
public function set(){}
public function get(){}
}
class Cache
{
public static function factory()
{
return new Redis();
}
}
$Cache = Cache::factory();
var_dump($Cache->set());
echo "<hr />";
?>
final 不被继承的,可以放到类或者方法的前面。
全局空间的类,前面加上"\"。(use \Test1;)
__autoload 当未找到引入的类,则会自动实现实例化类名的路由。
spl_autoload_register(function($className){
require str_replace("\\","/",$className . '.php');
});
替代__autoload自动加载类的方法。
当为类里面的属性加上“static”关键字后,可以直接通过类名调用。
类的后期静态绑定:子类中有父类的同名函数,继承之后,若想调用子类的同名函数,则父类的方法加“static::who()”。
魔术方法:
__set();__get();
__isset();判断私有属性(private)是否存在。
__unset();删除私有属性。
__call();调用的方法不存在时,自动调用此方法。
__callStatic();当发现调用的静态方法不存在时,则自动调用此方法。
__invoke();将对象以函数方式调用。test('go...');
__toString();直接打印对象函数。echo(test);
__clone();将浅拷贝,变成深拷贝。
PHP中对象的赋值是浅拷贝。深拷贝用clone。
trait类,可以用use方法调用。
interface接口类,不实现方法。
abstract抽象类,既可以定义接口,又可以实现方法。
单例模式和工厂模式:
单例模式同一个类,不用被实例化多次,从而节省内存。
类可以implements多个接口,接口可以extends一个接口
抽象类中定义的方法可以实现,也可以不实现。
单例模式能确保类只有一个实例
class Test{ private static $_instance=null; private function __construct(){ } private function __clone() { } public static function getIstance(){ if(!(self::$_instance instanceof self)){ self::$_instance =new self(); } return self::$_instance; } }
抽象类里面可以实现一个方法 接口里面不可以
接口可以被继承 但是不能被直接实例化
接口是类的模版 类是对象的模版 接口中定义的方法都是空方法 不做任何实现