⑴ php和c,c++的区别是什么
的区别:
一个有protected成员变量(假设为i)的类型Base,他的子类Derived直接继承自Base,同时Derived有一个成员函数func,他的参数是Base类型的,这个函数可以访问Base对象的protecte的成员吗?在C++中不可以,而在PHP中可以。
关于重载:
PHP中不支持C++中的重载,重新定义个函数(不管是参数相同还是不同,都会导致重复定义错误)。PHP有自己的重载方法,而且比C++中的更广泛,他不仅可以重载函数(通过使运散用__call()方法),还可以重载成员变量(通过使用__get()和__set())。而C++中只能对函数进行重载,而且重载的方法只有:不同的参数类型,不同的函数修饰符(const)。
关于abstract和interface
PHP中配悄余有这两个修饰符,因为PHP不支持对一个普通类的多继承,因此interface用于实现多继承。Abstract类在C++中也存在,只是实现方培滚式不一样,C++中使用pure virtual函数来表明这个类是抽象类,不能单独被实例化。而PHP中不仅可以使用函数的修饰符abstract(另外class前也必须标明abstract)来标明这个意思,也可以只使用abstract修饰符修饰class更直接的表明他是抽象类。另外, C++中的pure virtual函数不受访问类型的限制,不管是什么访问类型,都会被看作是public;而php中的abstract函数不能被声明成private,仅此而已。
多态
因为PHP是弱类型语言,所以他的多态性到处都有体现,导致他的多态性不像C++中那么明显。比如,在PHP中基类的函数可以看作全是virtual的,因此它不需要加任何修饰符,子类中和基类同名的函数都会被动态调用,而C++不一样,如果基类中的这个函数没有加virtual修饰符,子类中的那个同名函数就不会被动态调用,只能静态调用了。
操作符重载
PHP中不存在,而C++存在。重点在==操作符,在PHP中他可以运用在任何类型上,即使这个类型没有(像C++中一样)写自己的==重载函数。PHP中对于对象的比较,==表示两个对象的属性和值都一样,而且类型也一样;PHP也存在一个===操作符,表示他们引用了同一个对象,这跟java中很像吧。
final关键字
PHP中存在这个关键字,表示这个函数不能被重写(如果他用来修饰函数),或者类不能被继承(如果用类修饰class)。而C++中没有这个关键字,也无法模拟出那个效果。
对象赋值和拷贝
C++中的拷贝或者赋值大致有这三种方式。
一种是指针的赋值,即p1 = &obj,相当于PHP和java中的赋值操作;
另一种是memberwise assignment,也就是在obj1 = obj2时发生的事情,默认情况下执行浅度拷贝,和PHP中clone的效果一样。他可以通过重载赋值拷贝操作来执行你的深度拷贝或者其他自定义的拷贝,这就相当于PHP中的__clone()成员函数;
第三种是memberwise initialization,也就是在参数传递时,传递返回值时或者包含对象的容器初始化的时候自动运行的,你可以通过自己定义拷贝构造函数来控制它的效果。
拷贝构造函数在PHP中几乎用不到,因为他的传递是完全按引用传递,而不是对象的直接拷贝。
⑵ php反射在哪些场景有哪些作用
反射是在PHP运行状态中,扩展分析PHP程序,导出或提取出关于类、方法、属性、参数等的详细信息,包括注释。这种动态获取的信息以及动态调用对象的方法的功能称为反射API。反射是操纵面向对象范型中元模型的API,其功能十分强大,可帮助我们构建复杂,可扩展的应用。
其用途如:自动加载插件,自动生成文档,甚至可用来扩充PHP语言。
php反射api由若干类组成,可帮助我们用来访问程序的元数据或者同相关的注释交互。借助反射我们可以获取诸如类实现了那些方法,创建一个类的实例(不同于用new创建),调用一个方法(也不同于常规调用),传递参数,动态调用类的静态方法。
反射api是php内建的oop技术扩展,包括一些类,异常和接口,综合使用他们可用来帮助我们分析其它类,接口,方法,属性,方法和扩展。这些oop扩展被称为反射。
通过ReflectionClass,我们可以得到Person类的以下信息:
1)常量 Contants
2)属性 Property Names
3)方法 Method Names静态
4)属性 Static Properties
5)命名空间 Namespace
6)Person类是否为final或者abstract
然后就去看了看thinkphp的源码,对于MVC的实现也有不同的体验ThinkPHPLibCoreApp.class.php 中的exec方法
if(!preg_match('/^[A-Za-z](w)*$/',$action)){
//非法操作
thrownewReflectionException();
}
//执行当前操作
$method=newReflectionMethod($mole,$action);#查看方法
if($method->isPublic()){
$class=newReflectionClass($mole);#反射控制器
//前置操作
if($class->hasMethod('_before_'.$action)){
$before=$class->getMethod('_before_'.$action);
if($before->isPublic()){
$before->invoke($mole);
}
}
//URL参数绑定检测
if(C('URL_PARAMS_BIND')&&$method->getNumberOfParameters()>0){
switch($_SERVER['REQUEST_METHOD']){
case'POST':
$vars=$_POST;
break;
case'PUT':
parse_str(file_get_contents('php://input'),$vars);
break;
default:
$vars=$_GET;
}
$params=$method->getParameters();
foreach($paramsas$param){
$name=$param->getName();
if(isset($vars[$name])){
$args[]=$vars[$name];
}elseif($param->isDefaultValueAvailable()){
$args[]=$param->getDefaultValue();
}else{
throw_exception(L('_PARAM_ERROR_').':'.$name);
}
}
$method->invokeArgs($mole,$args);
}else{
$method->invoke($mole);#执行我们需要调用函数
}
//后置操作
if($class->hasMethod('_after_'.$action)){
$after=$class->getMethod('_after_'.$action);
if($after->isPublic()){
$after->invoke($mole);
}
}
⑶ php中抽象类和接口的区别
区别:
1、对接口的使用是通过关键字implements。对抽象类的使用是通过关键字extends。当然接口也可以通过关键字extends继承。
2、接口中不可以声明成员变量(包括类静态变量),但是可以声明类常量。抽象类中可以声明各种类型成员变量,实现数据的封装。(另JAVA接口中的成员变量都要声明为public static final类型)
<?phpabstract class Father { function meth1() { echo "meth1...<br>"; } abstract function meth2(); public $var1="var1"; public static $var2="var2"; const Var3="Var3";}class Son extends Father { function meth2() { echo "meth2 of Son...<br>"; }}$s=new Son();echo $s->var1."<br>";echo Father::$var2."<br>";echo Father::Var3."<br>";Interface IFather { //public $iVar1="iVar1"; 此处接口定义中不能包含成员变量 //public static $iVar2="iVar2"; 此处接口定义中不能包含静态变量 const iVar3="iVar3"; function iMeth1();}Class ISon implements IFather { function iMeth1() { echo "iMeth1...<br>"; }}$is=new ISon();echo IFather::iVar3;?>
3、接口没有构造函数,抽象类可以有构造函数。
4、接口中的方法默认都是public类型的,而抽象类中的方法可以使用private,protected,public来修饰。
5、一个类可以同时实现多个接口,但一个类只能继承于一个抽象类。
抽象类还是接口
1. 如果要创建一个模型,这个模型将由一些紧密相关的对象采用,就可以使用抽象类。如果要创建将由一些不相关对象采用的功能,就使用接口。
2. 如果必须从多个来源继承行为,就使用接口。
3. 如果知道所有类都会共享一个公共的行为实现,就使用抽象类,并在其中实现该行为。