更多
黑客联盟 黑客软件
学生黑客联盟
您现在的位置:学生黑客联盟 > 编程频道 > WEB开发 > 浏览信息
php代码之面向对象基础一
时间:2015-03-20 22:05 来源:www.stuhack.com 作者:学盟网
这篇文章不适合于初学者看,对php有一定了解的可以看一下,补充或者温故一下php面向对象里的一些特性。 一.何为面向对象? 介个问题,虽然略知一二,却感觉依然拿不出手,只能说将万事万物皆看为对象,只有在开发中才能体会出何为面向对象,只说也是徒然,但

这篇文章不适合于初学者看,对php有一定了解的可以看一下,补充或者温故一下php面向对象里的一些特性。

内容来自学生黑客联盟


本文来自学盟网(www.stuhack.com)

一.何为面向对象?

内容来自学生黑客联盟

介个问题,虽然略知一二,却感觉依然拿不出手,只能说将万事万物皆看为对象,只有在开发中才能体会出何为面向对象,只说也是徒然,但因为php大多用在web开发,所以,即使不使用面向对象也能运行的不错,之前在做c++开发时,设计给你个功能界面,看到这个界面,第一件事就是像美工切图一样的切成一个个的对象,然后,确定各个对象之间的关系,最后进行开发,哪儿都充斥着此思想。

copyright www.stuhack.com

什么是类?什么是对象? 学生黑客联盟 www.stuhack.com

类是一组集合的抽象,什么集合呢?是一组具有相似特性和操作的对象的集合。 www.stuhack.com

对象是某一个类的具体实例。 内容来自学生黑客联盟

毕业时候可能我会背给面试官听,可现在,虽然感觉理解的还是想书本上的语句一样的俗,但起码不用再靠脑细胞说出这两个定义。 内容来自学生黑客联盟


本文来自学盟网(www.stuhack.com)

二.php中的类结构 内容来自学生黑客联盟

php中类也是那些访问控制符,也是有属性和方法。 www.stuhack.com

学盟网

class Person {
    private $name = "PersonName";
    public static $gender = "PersonGender";
    
    public function test(){
        echo $this->name, '
'; } };

学生黑客联盟 www.stuhack.com

www.stuhack.com


copyright www.stuhack.com

三.构造函数

构造函数的名称为__construct,在构造函数这里我想强调的有以下几点:

学盟网

1. php不会像其他语言(c++或者java)那样,当实例化子类的时候会自动调用你的父类构造函数,php里需要手动调用父类的构造函数,这儿牵扯到继承,可以先看一下继承方面的东西。

学盟网

内容来自学生黑客联盟

class Person{
	public funciton __construct(){
		echo 'Person construct
'; } }; class Teacher extends Person{ public function __construct(){ //parent::__construct(); echo 'Teacher construct
'; } }; $t1 = new Teacher; //生成Teacher对象 本文来自学盟网(www.stuhack.com)

内容来自学生黑客联盟

运行结果:

copyright www.stuhack.com

Teacher construct

copyright www.stuhack.com

如果想要在生成子类时初始化父类的一些数据,需要手动调用父类的构造函数,打开注释行即可。 内容来自学生黑客联盟


www.stuhack.com

2. 一个类中不能写两个参数不同的构造函数。 本文来自学盟网(www.stuhack.com)

这儿牵扯到php中的一些规定,其他语言中,以下写法是正确的: 内容来自学生黑客联盟

学盟网

class Person{
	public funciton __construct(){
		echo 'Person construct
'; } public function __construct($param){ echo 'Person with param construct
'; } }; 内容来自学生黑客联盟


copyright www.stuhack.com

而在php是不允许的,究其根源为php是一种弱语言类型,对于类型的限制不是很敏感,进而提供了__call和func_get_args函数机制,因而可以用如下的方式实现: 学盟网

www.stuhack.com

class Person{
	public function __construct(){
		$param = func_get_arg(); //获取参数数据
		$param_num = func_num_args(); //获取参数个数
		if($param_num == 0){
		}else if($param_num == 1){
			if(is_array($param[0])){
				//...
			}
		}else{
			//...
		}
	}
}; www.stuhack.com 


内容来自学生黑客联盟

三.析构函数

学生黑客联盟 www.stuhack.com

析构函数是用于在此实例对象结束时,自动调用的函数,可以写入一下释放内存的语句来为实例的死亡画上完美的句号,这儿与构造相同,有继承关系时必须手动调用父类的析构,一个类中只有一个析构。

copyright www.stuhack.com


本文来自学盟网(www.stuhack.com)

四.控制访问符

学盟网

public:公共访问符,在类内,子类内,类外都可以访问此属性或方法。

学盟网

protected:受保护的访问符,只能在类内和其子类内访问此属性或方法,在类外不能访问。

本文来自学盟网(www.stuhack.com)

private:私有访问符,只能在本类内访问,属于本类私有东东,不能继承,不能重载,任何人访问不了。 www.stuhack.com


本文来自学盟网(www.stuhack.com)

五.魔术方法__get和__set

学生黑客联盟 www.stuhack.com

这两个方法的功能:对受保护和私有属性访问的一个访问器,可以对从类外接收到的数据进行安全性和合理性的校验。 学盟网

__set方法接收两个参数,第一个是属性名称,第二个是要赋的新值。 本文来自学盟网(www.stuhack.com)

__get方法接收一个参数,属性名称。

学盟网


copyright www.stuhack.com

1. public属性能提供在类外修改属性的服务,因此,对于public属性,不会走__get和__set流程。

学盟网

内容来自学生黑客联盟

class D{
    public $name = 'D name';
    protected $gender = 'male';
    private $age = 18;

    public function __set($name, $value){
        echo '__set
'; //if(in_array($name, ['name', 'gender', 'age'])) $this->$name = $value; } public function __get($name){ echo '__get
'; //if(!in_array($name, ['name', 'gender', 'age'])) return NULL; return $this->$name; } }; 内容来自学生黑客联盟


本文来自学盟网(www.stuhack.com)

本文来自学盟网(www.stuhack.com)

运行结果: 本文来自学盟网(www.stuhack.com) 
new D name //name为public属性,不会走get和set
__set
__get
new D gender
__set
__get
new D age 
内容来自学生黑客联盟

学生黑客联盟 www.stuhack.com

2. 我们也可以加入数据校验的功能,打开注释就可以进行校验。 内容来自学生黑客联盟

3.两个方法必须是public访问,否则会提示错误,我们可以从这两个函数的功能来出发思考,就不难想象为什么需要public访问控制。 copyright www.stuhack.com


本文来自学盟网(www.stuhack.com)

六.继承

学生黑客联盟 www.stuhack.com

终于到了可以让你的菊花开苞的特性,没有继承,所有类都是渣渣,因为有了继承,所以...问题就特么的一大波一大波的来啦...让我们来深入浅出一下此继承特性。 学生黑客联盟 www.stuhack.com

什么继承就不说了吧,文章的开头就有一个继承的小示例。 本文来自学盟网(www.stuhack.com)

有了继承会出现什么问题呢?想一下,如果B继承了A...真的是难以想象...

学生黑客联盟 www.stuhack.com

1. 构造函数,这个放心,跟继承没有太多关系,相当于两个类里的构造函数,但是怎么也有个父子关系啊,不能把事做的太绝,所以,上面讲过,如果有需要,可以手动调用父类的构造函数,可以看下上面的示例。

学盟网

2.单方向继承,继承是单方向的,子类可以从父类继承,但父类却不能从子类继承特性,示例:

copyright www.stuhack.com

内容来自学生黑客联盟

class A{
	public $attr1;
	public function oper1(){
	}
};

class B extends A{
	public $attr2;
	public function oper2(){
	}
};
//子类可以继承父类
$b = new B;
$b->oper1();
$b->attr1 = 'attr1 value';
$b->oper2();
$b->attr2 = 'attr2 value';

//父类不能继承子类
$a = new A;
$a->oper2();//出错
$a->attr1();//出错 www.stuhack.com 

内容来自学生黑客联盟

3. 重载,一提到php的重载就特别别扭,因为他的重载放到其他语言里叫做重写overwrite,我还是习惯将这个特性说为重写,大家随便。

copyright www.stuhack.com

<1>public重载:

本文来自学盟网(www.stuhack.com)

学盟网

class E{
    public $attr1 = 'E attr1 value';
    public function oper1(){
        echo 'E oper1
'; echo 'attr1 value = ', $this->attr1, '
'; } }; class F extends E{ public $attr1 = 'F attr1 value'; public function oper1(){ //parent::oper1(); echo 'F oper1
'; echo 'attr1 value = ', $this->attr1, '
'; } }; $f = new F; $f->oper1(); www.stuhack.com

学生黑客联盟 www.stuhack.com

运行结果:

copyright www.stuhack.com

F oper1
attr1 value = F attr1 value

copyright www.stuhack.com


本文来自学盟网(www.stuhack.com)

F继承了E并且重写了E的attr1和oper1,因此,在调用oper1时,$this->attr1显示F attr1 value,如果打开注释parent::oper1调用父类的Oper1方法,运行结果如下: 学盟网

E oper1
attr1 value = F attr1 value //attr1属性已经被子类重写的attr1属性覆盖
F oper1
attr1 value = F attr1 value
学盟网

可以看出子类重写父类的属性和方法后,会覆盖父类相应的属性和方法。

学生黑客联盟 www.stuhack.com


内容来自学生黑客联盟

<2>private重载

本文来自学盟网(www.stuhack.com)

学盟网

class E{
    private $attr1 = 'E attr1 value';
    public function oper1(){
        echo 'E oper1
'; echo 'attr1 value = ', $this->attr1, '
'; } }; class F extends E{ public $attr1 = 'F attr1 value'; public function oper1(){ parent::oper1(); echo 'F oper1
'; echo 'attr1 value = ', $this->attr1, '
'; } }; $f = new F; $f->oper1(); copyright www.stuhack.com
以上代码只变动了一处地方,就是把父类$attr1的访问属性变成private,那重载机制如何执行呢?先看运行结果:

本文来自学盟网(www.stuhack.com)

E oper1
attr1 value = E attr1 value //父类私有的属性
F oper1
attr1 value = F attr1 value

学盟网


本文来自学盟网(www.stuhack.com)

之前我们说过,private属性和方法子类是继承不了的,这种情况,遵循一个原则: 学生黑客联盟 www.stuhack.com

private属性在那个类里调用的,就显示哪个类里的属性值。

学生黑客联盟 www.stuhack.com

示例中的parent::oper1方法调用的是E类的oper1方法,在E的oper1方法内又调用了$this->attr1,attr1是private并没有被子类继承,因此,调用的就是类E里的attr1属性值。 学盟网


学生黑客联盟 www.stuhack.com

<3>protected重载与public重载一致 学盟网


copyright www.stuhack.com

<4>类属性的继承

学生黑客联盟 www.stuhack.com

www.stuhack.com

class G{
    public static $attr1 = 'G attr1 value';
    public function oper1(){
        echo 'G oper1
'; echo 'attr1 value = ', self::$attr1, '
'; } }; class H extends G{ public static $attr1 = 'H attr1 value'; public function oper1(){ parent::oper1(); echo 'H oper1
'; echo 'attr1 value = ', self::$attr1, '
'; } }; $h = new H; $h->oper1(); 本文来自学盟网(www.stuhack.com)

学生黑客联盟 www.stuhack.com

运行结果: www.stuhack.com

G oper1
attr1 value = G attr1 value
H oper1
attr1 value = H attr1 value

学生黑客联盟 www.stuhack.com

其实不管G类的attr1属性是public还是private,结果都一样。

学生黑客联盟 www.stuhack.com

个人是这么理解的,类属性可以继承,但谈不上重载,那关于子类调用父类的属性也有一规则: copyright www.stuhack.com

self或者parent只代表本类,因此,根据这一原则可以断定,属性的值一定是本类属性的值,与子类无关。(特殊情况时php的静态延迟加载机制)。

学生黑客联盟 www.stuhack.com


内容来自学生黑客联盟

七.静态延迟加载 内容来自学生黑客联盟

既然已经提到了静态延迟加载,就趁热打铁讲一下,H和G的例子大家已经看了,那我就是想要在子类中调用父类的东东怎么办?静态延迟加载就是解决这个问题,请看两个示例:

内容来自学生黑客联盟

示例1: 学生黑客联盟 www.stuhack.com

还是H和G类的例子 copyright www.stuhack.com

www.stuhack.com

class G{
    public static $attr1 = 'G attr1 value';
    public function oper1(){
        echo 'G oper1
'; echo 'attr1 value = ', static::$attr1, '
'; } }; class H extends G{ public static $attr1 = 'H attr1 value'; public function oper1(){ parent::oper1(); echo 'H oper1
'; echo 'attr1 value = ', self::$attr1, '
'; } }; $h = new H; $h->oper1();
内容来自学生黑客联盟
运行结果:

本文来自学盟网(www.stuhack.com)

G oper1
attr1 value = H attr1 value
H oper1
attr1 value = H attr1 value

copyright www.stuhack.com

上面代码只是将G类里的self::$attr1改写成了static::$attr1,运行结果就不一样了 本文来自学盟网(www.stuhack.com)


学生黑客联盟 www.stuhack.com

示例2: 本文来自学盟网(www.stuhack.com)

学生黑客联盟 www.stuhack.com

class I {
    public static function who(){
        echo __CLASS__, '
'; } public static function test(){ static::who(); } }; class J extends I{ public static function who(){ echo __CLASS__,'
'; } };
copyright www.stuhack.com

学生黑客联盟 www.stuhack.com

运行结果: copyright www.stuhack.com

J 学生黑客联盟 www.stuhack.com


学生黑客联盟 www.stuhack.com

通过这两个例子,可以好好的领悟一下static的静态延迟绑定。 本文来自学盟网(www.stuhack.com)


学盟网

写的有点多,主要是因为一牵扯继承就停不下来....面向对象还有一些只是点,后面有时间再补上吧...谢谢,如若有错误的地方,敬请大家指出,随时更正,谢谢!!

内容来自学生黑客联盟


copyright www.stuhack.com


www.stuhack.com




本文标题:php代码之面向对象基础一

本文地址:http://www.stuhack.com/bc/web/032014277.html

免责声明:本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。




百度钱包“落子

一个商户通过审核入驻百度钱包,将获得百度[查看详细]

移动搜索&发

移动搜索在移动端的创新和颠覆也为百度探索[查看详细]

张向宁:移动互联

张向宁回顾了他2002年提出的“互联网十大预[查看详细]

淘宝开卖二维码门

截至4月20日,淘宝已经售出车展的实体门票[查看详细]

百度钱包杀入移动

“百度钱包”将完成的 “搜索用户”与“消[查看详细]