0
点赞
收藏
分享

微信扫一扫

php 魔术方法

b91bff6ffdb5 2022-02-09 阅读 152

封装

使用修饰符修饰成员属性和成员方法,最大限度的隐藏对象的内部细节,保证对象的完整性和安全性

对象把变量和函数用大括号装在一起

即 对象 = {成员属性+成员方法} = {变量 + 函数}

强调的是一个整体性.

对象内部, 成员方法可以直接访问成员属性. 因此,方法之间传递数据非常方便.

public 公有的

类的成员属性和成员方法, 可以在类的 外部 读取和调用.

如果成员方法前没有任何修饰符, 则默认为 public

class Person 
{ 
	public $name;
    
	public function setName($str) 
	{ 
        // 直接给成员属性赋值 
        $this->name = $str; 
	}
    
	public function getName() 
	{ 
        // 直接访问成员属性 
        return $this->name; 
	} 
}

private 私有的

类的成员属性和成员方法, 只能在类的 内部 读取和调用.

私有的成员属性在类的外部 不能直接访问

私有的成员方法在类的外部 不能直接调用

// 借钱给朋友 
class Person 
{ 
	private $card; // 银行卡 
	private $password; // 密码 
	private $money; // 身上的现金 
	
	// 取钱 
	private function qu_qian() 
	{ 
		$this-> money = 银行->atm($this->card, $thid->password); 
	}
	
	// 借给别人钱 
	public function gei() 
	{ 
		$this->qu_qian(); // 取钱是对象自己完成的, 不需要别人知道, 所以也是私有. 
		return $this->money; 
	} 
}

protected 受保护的

类的成员属性和成员方法, 只能在本类和子类中的 内部 读取和调用.

受保护的成员属性在类的外部    不能直接访问     

受保护的成员方法在类的外部    不能直接调用

class Person 
{ 
    protected $name;
    protected $sex; 
    protected $age; 
    
    protected function getAge() 
    { 
    	return $this->age; 
    } 

    public function setAge($n) 
    { 
        if ($n>=0 && $n<120) { 
            $this->age = $n; 
        } else { 
            echo '设置年龄不在合理范围内!'; 
        }
    }
   
}

魔术方法

__get 获取对象中的非公有或不存在的成员属性时, 触发该方法 接受一个参数 属性名

__set 设置对象中的非公有或不存在的成员属性值时, 触发该方法 接受两个参数 (属性名,属性值)

class Test 
{ 
	private $name = '景水'; 
	private $sex = '男'; 
	private $age = 18; 
	
	// $prop 为要获取的属性名称 
	public function __get($prop) 
	{ 
		return $this->$prop; 
	}
	
	// $prop 为要设置的属性名称, $value 为要设置的具体值 
	public function __set($prop, $value) 
	{ 
		$this->$prop = $value; 
	} 
	
}
	
$obj = new Test; 
echo $obj->name; 	// 触发 __get() 
$obj->sex = '女'; 	// 触发 __set() 
	
/* 
	这两个方法代替了多个 getXXX 和 setXXX 方法 
	从使用类的角度, 不需要知道 getXXX 和 setXXX 方法, 
	只是把成员属性当做public来使用即可, __get 和 __set 会自然的,
	透明的起到 保护对象的目的. 
*/

__call() 调用对象中非公有或不存在的成员方法时, 触发该方法 接受两个参数 触发场景:

class Test
{

    // 私有方法,不能在外部直接调用 
    private function add($a, $b) 
    {
    	return $a + $b; 
    }
    
    // $method 为要调用的方法名, $params 为调用方法时的参数数组 
    public function __call($method, $params) 
    { 
    	return $this->$method(...$params); 
    }
}

$obj = new Test; 
echo $obj -> add(3, 4); 	// 触发 __call() 返回 7 

/* 
	有一种场景,可以利用__call在 原方法执行前,执行后添加代码.
	如: 
	public function __call($method, $params) 
	{ 
		// 前置代码 $this->$method(...$params); // 后置代码 
	} 
*/

其它魔术方法

__isset 判断对象的非公有或不存在的属性时, 触发该方法 接受一个参数 属性名

__unset 销毁对象的非公有或不存在的属性时, 触发该方法 接受一个参数 属性名

class Test 
{ 
    private $name = '景水'; 
    private $sex = '男'; 
    private $age = 18; 

    // 返回真实的结果 $prop 要判断的属性名 
    public function __isset($prop) 
    { 
    	return isset($this->$prop); 
    }

    // 实现销毁私有属性 $prop 要销毁的属性 
    public function __unset($prop) 
    { 
    	unset($this->$prop);
    }
}

$obj = new Test; 

isset($obj->name); // 触发 __isset() 
unset($obj->sex);  // 触发 __unset()

__clone 当对象被克隆时,触发该方法

class Test 
{ 
    private $name = 'wangjs'; 

    public function __clone() 
    { 
    	$this -> name = '上神'; 
    } 
}

$obj1 = new Test; 

$obj2 = clone $obj1; // 触发 __clone

__invoke 当对象被当做函数调用时, 触发该方法

class Test 
{ 
    public function __invoke() 
    { 
    	echo '你把我当成函数调用啦!'; 
    } 
}

$obj = new Test; 
$obj(); 	// 触发 __invoke(), 可以用参数

__toString 当在脚本中直接对对象进行字符串操作的时候 触发该方法

作用: 代替对象进行字符串的操作

<?php
	class A
	{
		public $name;

		public function say()
		{
			return 100;
		}

		public function __toString()
		{
            //在方法中必须要返回一个字符串类型的值
			return '100';
		}
	}

	$a = new A;

	echo $a;
?>

继承

就是别人有 但是我没有 这个时候需要使用继承 把它所有的东西都拿过来

//基本格式
class A 
{ 
    public $name='王建双';
    
    public function say()
    {
    	echo '水清则无鱼';
    } 
}

// B类具有A类所有的成员. B类为子类, A类为父类
class B extends A  
{
    // 这里面什么都不写, 也已经有A中的成员属性和成员方法
    
    // 添加 成员属性 和 成员方法
    public $sex = '男'; 

    public function listen()
    {
    	echo '认真听讲,不睡觉!<br>';
    } 
}

$b = new B; // 访问从父类继承的成员 

echo $b -> name,'<br>'; 
$b -> say(); // 访问父类独有的成员 

echo $b -> sex,'<br>'; 
$b -> listen();

/*
注意:
	1)  B 中还可以 添加 新的成员属性和方法
	2)  B 中还可以 重写 已有的成员方法.
	
	重写成员方法的时候, 参数个数要一致, 构造方法可以不一致
*/

父类中的 私有成员( private ) 在子类中无法访问.

父类中的 受保护的 ( protected ) 修饰成员, 使成员在子类中也可以访问.

       	 本类 	 子类 	类的外部

public Y Y Y
private Y N N
protected Y Y N

单继承

在php中只支持单继承

// 父类 --- 人 
class Person 
{ 
    public $name; 
    public $sex; 
    public $age; 
    public function say(){} 
}

// 学生类 继承 人类 
class Student extends Person 
{ 
    public $num; 
    public function write(){} 
}

// 教师类 继承 人类 
class Teacher extends Person 
{ 
    public $money; 
    public function teach(){} 
}

/*
	单继承是一次只能继承一个类,不能连续继承多个类
*/

子类的重载

1.如果子类对父类的方法进行重写之后,实例化的对象在调用该方法的时候,会调用子类方法.

2.如果在子类的方法中想调用父类中的同名方法,这个需要使用 parent::方法名()

3.子类中重写成员方法的时候,要求参数个数和类型要一致,但是构造方法可以不一致

class A
{
    public $name; 
    
    public function __construct($name) 
    { 
    	$this->name = $name; 
    }
    public function add($a, $b) 
    { 
    	return $a + $b; 
    }
}

class B extends A 
{ 
    public $sex; 
    // 重写构造方法时,参数可以不一致 
    public function __construct($sex, $name) 
    { 
    	parent::__construct($name); 
    	$this -> sex = $sex; 
    }
	
	// 重写父类方法时,还要求参数一致(个数,类型) 
    public function add($x, $y) 
    {
        parent::add($x, $y);
    } 
}

$b = new B; 
echo $b -> add(3, 4);

final 关键字

用来修饰类和成员方法, 用final修饰的类可以实例化对象但不能被继承 修饰的方法可以被调用但不能被重写

// 表示本类不能被继承 
final class A 
{ 
    // 表示该方法不能被重写 
    final public function say() 
    { 
    	echo '就算你叫破喉咙我也会继续写下去!'; 
    } 
}

trait 关键字

与 class 相似, 但是用 trait 定义的结构不能实例化对象

通过在类中使用use 关键字,声明要组合的Trait名称

trait A
{
    public function say()
    {
        echo '说话的方法.....';
    }
}

trait B
{
    public function eat()
    {
        return '吃饭的方法.....';
    }
}

class C 
{
    // 使用 trait A和B 做为本类的组装零件 
    use A,B;
    public function talk()
    {
        return '一起出去走走呀....';
    }
}

class D extends C
{ 
    public function run()
    {
        return '已在运行起来了.....';
    }
}
举报

相关推荐

0 条评论