方法的重写 override
- 方法的重写就是子类有一个方法,和父类(基类)中的某个方法的名称、参数个数都一样,那么我们就说子类的这个方法重写了父类的那个方法
- 重写必须放生在继承的基础上
- final修饰的类方法不可被子类重写
- 私有属性/方法不能重写
Java方法的重载 overload
Java方法重载【正宗】
- 一个类中存在多个同名方法,但参数类型/个数不同,传不同的参数,调不同的方法,这种特性叫重载。
- 真正的重载php做不到 ,php同一作用域中函数名不能相同
// 真正的重载php做不到 php同一作用域中函数名不能相同
// 这代码在php中是错的!
class A{
public function say($n){
echo 'hello';
}
// Fatal error: Cannot redeclare A::say()
protected function say($n,$m){
echo 'shit';
}
}
$a = new A();
$a->say(1);
$a->say(1,2);
php中方法的重载
php方法重载【伪】
- php中,不允许存在多个同名方法,因此,不能完成java/c++意义上的重载
- php虽然支持重载,但此重载非彼重载,在具体实现上和Java有较大区别
- php的重载是指,通过魔术方法动态的创建属性和方法
使用魔术方法__call,实现非静态方法的重载
class A{
public function fun1($n){
echo $n;
}
protected function fun2($n,$m){
echo $n+$m;
}
public function __call($name, $arguments){
if ($name == 'test'){
if (count($arguments) == 1){
echo $this->fun1($arguments[0]);
}elseif(count($arguments) == 2){
echo $this->fun2($arguments[0],$arguments[1]);
}else{
echo '调用的方法名有误';
}
}
}
}
$a = new A();
$a->test(1,2);
使用魔术方法__callStatic,实现静态方法的重载
class A{
public static function fun1($n){
echo $n;
}
protected static function fun2($n,$m){
echo $n+$m;
}
public static function __callStatic($name, $arguments){
if ($name == 'test'){
if (count($arguments) == 1){
echo self::fun1($arguments[0]);
}elseif(count($arguments) == 2){
echo A::fun2($arguments[0],$arguments[1]);
}else{
echo '调用的方法名有误';
}
}
}
}
A::test(1);
不使用魔术方法也能达到重载的效果,但概念上不能叫重载
利用func_get_args()
函数,将传来的参数保存为数组,然后再判断,达到重载的效果,php太灵活了!
class Human{
public function say(){
// 判断对象调用area时,得到的参数个数,保存为数组返回
$args = func_get_args();
if (count($args) == 1){
echo 'xxxx';
}elseif(count($args)==2){
echo 'zzzz';
}else{
echo 'oooo';
}
}
}
$a = new Human();
$a->say(1,2,3);
php中属性的重载
- 对象为不存在的属性赋值时,php会调用默认__set()方法动态的增加实例属性
- 如何限制这种机制? 写一个__set()方法,什么都不做,覆盖默认的就行了
class Cat{
private $name = '大橘';
//public function __set($name, $value){}
}
$c = new Cat();
$c->age = 1; // 执行这句代码时 发生了什么? 虽然没写但还会调用__set()魔术方法,动态的创建该属性(对象层面)
print_r($c); // Cat Object([name:Cat:private]=>大橘 [age]=>1)