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

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

WBOY
WBOYOriginal
2016-06-23 14:12:07903browse

/// 问题看如下代码
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

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn