首頁  >  文章  >  後端開發  >  问个子类对象直接调用基类内被重载的函数的问题?

问个子类对象直接调用基类内被重载的函数的问题?

WBOY
WBOY原創
2016-06-23 14:12:07904瀏覽

/// 问题看如下代码
class A
{
function A()

$this->nNum = 1024;
}
function SelfClass()
{
echo "class A
";
}
}

class B extends A
{
function SelfClass()
{
echo "class B
";
}
}
?>

$obj = new B();
$obj->SelfClass(); // 调用B类的函数SelfClass()函数
/* 如何能使用对象obj的基类的SelfClass()函数?
C++下可以写类似的代码$obj->A::SelfClass(),那么PHP可以如何实现呢?*/
?>


回复讨论(解决方案)

我所求的并非类似这种答案
class B extends A
{
function SelfClass()
{
echo "class B
";
}

function SelfClassX()
{
parent::SelfClass();
}
}

php没有提供这样的语法,不过可以模拟一下,但是不是很推荐这样用

<?phpclass A{	function A()	{ 		$this->nNum = 1024;	}	function SelfClass()	{		echo "class A<br>" . $this->nNum . "<br>";	}	function __call($name, $arguments) {		list($class_name, $function_name) = explode('_', $name);				if(is_subclass_of($this, $class_name))		{			if ($class_name == __CLASS__)			{				self::$function_name();			} 			else 			{				$class_name::$function_name();			}		}	}}class B extends A{	function B()	{		$this->nNum = 2048;	}	function SelfClass()	{		echo "class B<br>" . $this->nNum . "<br>";	}	}class C extends B{	function C()	{		$this->nNum = 4096;	}	function SelfClass()	{		echo "class C<br>" . $this->nNum . "<br>";	}	}$obj = new B();$obj->SelfClass(); // 调用B类的函数SelfClass()函数$obj->A_SelfClass();$obj = new C();$obj->SelfClass(); // 调用C类的函数SelfClass()函数$obj->A_SelfClass();$obj->B_SelfClass();

这种语法$class_name::$function_name();编不过。
而且self::$function_name();的使用前提是$function_name()是静态函数。

<?php/// 折中地写了个实现,不完善,因为当C类继承B类时无法动态实现类的判断,语法不允许只能写硬代码类似于(A::$function_name(),B::$function_name())。class A{    function A()    {         $this->nNum = 1024;    }    function SelfClass()    {        echo "class A<br>" . $this->nNum . "<br>";    }     function __call($name, $arguments)	{        list($class_name, $function_name) = explode('_', $name);		if(method_exists($this, $function_name) && is_a($this, $class_name))		{			if(is_subclass_of($this, $class_name))			{						A::$function_name();			}			else			{				$this->$function_name();			}		}    }} class B extends A{    function B()    {        $this->nNum = 2048;    }    function SelfClass()    {        echo "class B<br>" . $this->nNum . "<br>";    }    }$obj = new B();$obj->B_SelfClass(); // 调用B类的SelfClass()函数$obj->A_SelfClass(); // 调用A类的SelfClass()函数 

不太明白你这么做的意义
但至少 21 行的 A::$function_name();
应写作 $class_name::$function_name();
否则就不具普遍性了

$class_name::$function_name();这写法是有语法错误的。你不可以这样子写啊。
$class_name只能解析为字符串,无法使用这种语法。你想法是美好的但实现不了

这可不只是美好的愿望!实测证明写作 $class_name::$function_name() 是正确的(php5.4.12)

但需要注意的是:
无论是写作 $class_name::$function_name()
还是写作 A::$function_name()
都是不符合 php 语法的,因为需要 $function_name 是静态方法,而这里的不是

而在这里 php 没报错,显然是一个 BUG

对你的提出的写法我这边的测试环境没法实现,而且你说不行的,我这边能测试通过。
我实测过A::$function_name()是可以的,这个调用并不需要 $function_name 是静态方法。
而且$class_name::$function_name()这种写法我测过是无法把$class_name解析为类来用的
只能解析为字符串。难道是我的PHP版本太老了!!!

A::SelfClass(); //Strict Standards:  Non-static method A::SelfClass() should not be called statically 这是正常的语法错(可屏蔽)
$function_name = 'SelfClass';
A::$function_name(); //这里不报语法错是不正常的

在一个系统里是不应该存在双重标准的!

我的是PHP Version 5.2.6

我在一本书上找到了A::$function_name();类似这个语法的用例

这段出自《PHP与MySQL程序设计》第4版

类名::方法名 这种写法古来有之,这是到了 php5.3 才开始有了限制

我之前用的都是C++,学习PHP时总是惯性认为某些用法应该差不多。

C++是编译执行的,所以源码被扫描几遍都无所谓
php是解释执行的,多扫描一遍都会影响执行效率

如果你自己去写解释器,你就会发现有很多二义性问题在二遍扫描中都无法解决

版主提到二义性问题确实是重点。想问一下版主,我原来是做C++游戏开发的,想改行做网站
作为一个PHP程序员的话,需不需要学习javascript,而基础html的话要学习到什么程度。

直接使用反射吧,php5.2 php5.3 都可以测试通过

<?phpclass A{	function A()	{ 		$this->nNum = 1024;	}	function SelfClass()	{		echo "class A<br>" . $this->nNum . "<br>";	}	function __call($name, $arguments) {		list($class_name, $function_name) = explode('_', $name);				if(is_subclass_of($this, $class_name))		{			//反射一个方法			$reflectionMethod = new ReflectionMethod($class_name, $function_name);			// 使用当前对象调用			$reflectionMethod->invoke($this);		}			}}class B extends A{	function B()	{		$this->nNum = 2048;	}	function SelfClass()	{		echo "class B<br>" . $this->nNum . "<br>";	}	}class C extends B{	function C()	{		$this->nNum = 4096;	}	function SelfClass()	{		echo "class C<br>" . $this->nNum . "<br>";	}	}$obj = new B();$obj->SelfClass(); // 调用B类的函数SelfClass()函数$obj->A_SelfClass();$obj = new C();$obj->SelfClass(); // 调用C类的函数SelfClass()函数$obj->A_SelfClass();$obj->B_SelfClass();

那么参数传递呢?

发射方法确是好思路,但参数问题较为麻烦。

我想大概可以用evla()函数来解决吧

写错了,应该为void eval(string code_str);

那么参数传递呢?

没有那么麻烦
class A
{
function A()

$this->nNum = 1024;
}
function SelfClass($a,$b,$c,$d,$e,$f)
{

echo "class A
" . $this->nNum . "
" . "$a,$b,$c,$d,$e,$f". "
";
}

function __call($name, $arguments) {
list($class_name, $function_name) = explode('_', $name);

if(is_subclass_of($this, $class_name))
{
//反射一个方法
$reflectionMethod = new ReflectionMethod($class_name, $function_name);

// 使用当前对象调用
$reflectionMethod->invokeArgs($this, $arguments);
}


}
}

class B extends A
{
function B()
{
$this->nNum = 2048;
}
function SelfClass()
{
echo "class B
" . $this->nNum . "
";
}
}

class C extends B
{
function C()
{
$this->nNum = 4096;
}
function SelfClass()
{
echo "class C
" . $this->nNum . "
";
}
}

$obj = new B();
$obj->SelfClass(); // 调用B类的函数SelfClass()函数

$obj->A_SelfClass(1,2,3,4,5,6,7);

$obj = new C();
$obj->SelfClass(); // 调用C类的函数SelfClass()函数

$obj->A_SelfClass(1,2,3,4,5,6,7);
$obj->B_SelfClass();

喔,确实是很好地解决了。感谢hnxxwyq

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn