PHP杂文一篇1

来源:互联网 发布:将无线设备添加到网络 编辑:程序博客网 时间:2024/06/05 09:57

来说一下,什么是面向对象。就来说一下。c语言主要是集中在面向过程。而面向过程就主要是集中在算法。面向对象就是从面向过程演变过来的,而这里,值得一说的语言就是smalltalk语言。这个语言被称为“面向对象编程之母”,它也是历史上第一个真正的集成开发环境。也就是我们时常所说的IDE

我觉得smalltalk的成功,也要取决于simula语言,因为simula语言引入了类,继承,之类等面向对象当中的一些非常重要的概念。

一种系统的诞生,往往或受到硬件平台的很多限制,最成功的莫过于就是把这个系统可以完美的移植到通用的硬件平台上面,这样也才方便大众所使用。

好了,来说一下什么是类和对象

类:简单点说,就是相同事务的合集。我们可以从这些事务中抽取出它的属性与行为(方法)

比如狗类,不管是什么品的狗,都有嗅觉,名字,毛发的颜色,叫声,还有四条腿。

又比如人类,好像说人类有点大,就说一下比如学生类:有姓名,学号,学校,班级,专业这些完全可以抽象出来表示。一个类就可以表示很多学生。

虽然不同的语言处理方法不一样,但是原理都是一样的。

那什么又是对象?

就是抽象出来的一个具体的实体,对象是类的实例化。

好了,继续向下面延伸,又不得不说面向对象的几个重要的特征。

 

第一个是面向对象的封装性:就比如家里面安装的电灯,你只需要它亮了就行了,至于里面的电路是如何安装的,你完全可以不用去理会。

那么它又有几个特点:

第一个信息隐藏

第二个以完整的形式进行呈现

第三个信息保护

只保留有效对外接口与之联系。

封装提高了类的可重用性。

 

下面来说一下,面向对象的第二个特征,继承。

打个比方,用java写一个播放器我们只需要不到100行代码,但是用c写一个播放器,就要接近200多行代码.

因为java是一个面向对象语言,它可以继承父类做好的一些方法与属性,避免了很多麻烦的工作。

 

当然,还有一个特性就是多态,本身面向对象就是多态的。

  这里来说一下,面向对象编程的几个特点。

重用性,灵活性和扩展性

这里来说一下内存分配的问题,内存分为四个区

一个堆区,一个栈区,一个全局区,一个代码区。

一般来说我们声明的变量就是放在栈区的。存放的是占用空间小的数据类型的地方。栈区的数据,我们可以直接获取,然后操作,修改。

而对象就是存放在堆区的。堆上的数据不可以直接修改。

new一个对象,就会堆上面开辟一段内存空间。

下面就是来介绍一下php中四个魔术方法的使用。

__set()__get()__isset(),__unset()

上面这些魔术方法,不需要我们手动去调用,它是自动调用的。

一般来说,我们总是把类的属性定义为private,这样更符合逻辑。但是,我们对属性的读取与赋值又是非常频繁的,所以,我们要用到上面四个魔术方法。

下面我们来看一下代码:

<?php

header("Content-type:text/html;charset=utf-8");

class Person

{

private $name;

private $age;

private $sex;

public $number;

 

public function __construct($name,$age,$sex,$number)

{

//在类的内部,要访问属性与方法,要用到$this

$this->name=$name;

$this->age=$age;

$this->sex=$sex;

$this->number=$number;

}

private function say()

{

echo "我正在学习<br/>";

}

public function __get($property_name)

{

//注意这个方法设置成public,不需要手动调用,自动调用的,得到私有属性

return $this->$property_name;//直接返回这个属性

}

public function __set($property_name,$value)

{

//这个也是自动调用的,设置成public

$this->$property_name=$value;

}

public function __isset($property_name)

{

//这个主要是针对于isset函数起的一个作用

//isset函数主要是去检测对象里面的成员属性有没有被设定

//但是它只是针对公有的成员有效

//当我们设置了这个魔术方法,那么私有的也会有效了

return isset($this->$property_name);

}

public function __unset($property_name)

{

//这个方法的使用与上面方法的使用原理都是一样的

//注意unset是没有返回值的

unset($this->$property_name);

}

}

$p1=new Person("周杰伦","35","","28");//实例化一个对象

echo $p1->name."<br/>";//此时已经自动调用了__get方法

$p1->name="张学友";//自动调用__set()方法

echo $p1->name."<br/>";//张学友

//去判断一个私有成员有没有被设定

if(isset($p1->name))

{

echo "isset此时针对于私有成员有效<br/>";//这个时候很明显会走这一条路

}else

{

echo "isset仍然没有任何效果<br/>";

}

unset($p1->name);

echo $p1->name."<br/>";//这个时候吗,这个私有成员就会看不到结果

上面说到了继承,那么就还是要来说一下继承这个东西。

继承就用关键字extends就好了,php只能是你单继承,也就是说,一次只能继承一个父类。我们这里引申出一个话题,覆盖,我们知道php里面是不可以定义同名方法的。如果一个类中定义了同名方法,php就会报错。

但是继承可以,当我们继承父类之后,我们就声明同名方法,就会把父类的方法给覆盖掉。

那么这个时候,问题也就来了,怎么在子类中调用父类中被覆盖的方法。

这里提供了两种方法使用。

父类的类名::被覆盖的方法名

parent::覆盖的方法名

 

下面对访问类型做一个简单说明

private:只能在同一个类中访问

protected:能在同类中访问,能在类的子类中访问,不能被外部成员访问

public:权限最大

 

final关键字只可以用来定义类和定义方法,不能使用final关键字来定义成员属性。

使用final关键字标记的类不能被继承。被标记的方法不可以被覆盖。

 

这里来说一下静态方法与静态属性。

静态方法与静态属性是独立于对象而存在,这个有个先后的依存关系,把这个关系搞清楚了,也就知道什么是可以访问,什么不能访问。它是存放在全局区的。

因为静态方法与属性是独立于对象这个东西而存在的,所以,不需要实例对象我们就可以访问。

直接用类名::属性 类名::方法就可以访问。

这个里面还有依存关系。类里面的静态方法是不能访问类的非静态成员的。因为有可能这些非静态成员根本就没有存在。

那么普通方法当然是可以访问静态方法与静态成员了,因为静态成员早就是于普通方法存在而存在的。

这里我们知道在类里面,要访问里面自身的成员,是需要$this这个关键字的。而$this就代表了这个对象。但是,我们知道,静态成员是先于对象而存在的,所以,它不可以用$this这个关键字。而是self::成员属性

下面在来说一个魔术方法。

__toString()方法

一般情况来说,我们不能用echo来直接输出一个对象。

New一下就会放到堆里面去。

而变量就会有一个指针指向这个位置。

 

上面直接输出就会报这样一个错误。

所以,这个时候,我们就需要用到__toString()方法

public function __toString()

{

return $this->name;

}

这样输出一个$p这样的引用就没有问题,__toString返回什么,输出什么。

下面,再来简单的说一下,对象的克隆。

也就是两个或者多个对象。

当然就是”clone”这个关键字。

$p1=new Person("周杰伦","38","");

$p2=clone $p1;

我们可以直接用clone这个关键字来进行克隆。但是这个是就像一个模子刻出来的一样,如果,我们想克隆的时候,稍加修改又怎么处理。

这个时候,就要用到魔术方法__clone(),我们直接在这个方法里面重写原本的属性。

public function __clone()

{

$this->name="张学又";

}

echo $p1->name."<br/>";//周杰伦

echo $p2->name."<br/>";//张学友

下面再来说一下__call

这个方法有两个参数,一个是函数的名字参数$function_name,另外一个是一个数组参数。$args,这个方法的作用就是,当调用一个不存在的方法的时候,代码不会报错,而是会继续执行下去,我们可以看一下如果没有这个魔术方法,代码的报错情况:

Fatal error: Call to undefined method Student::say() in D:\php2016\2017\test4.php on line 24

<?php

header("Content-type:text/html;charset=utf-8");

class Student

{

private $name="张学友";

private $age="20";

private $sex="";

public static $s="2000";

 

private function say1()

{

echo "我可以说话<br/>";

}

 

public function __get($property_name)

{

return $this->$property_name;

}

public  static function action1()

{

echo "我的工资是".self::$s."<br/>";

}

 

public function __call($function_name,$args)

{

echo "你所调用的函数".$function_name."不存在"."<br/>";

}

}

$s1=new Student();//实例化一个对象

$s1->say();

echo $s1->name."<br/>";

echo Student::$s."<br/>";

Student::action1();

这里我们必须注意,静态属性内外部访问,都要加上$符号,还有就是,静态属性方法最好设置成public,它是放在全局区的。

 

 

下面来说一下抽象方法抽象类

abstract fucntion say();//这个就是抽象方法。

抽象方法简单点说是你没有实体存在的方法。

注意,类里面只要一个方法是抽象方法,这个类也就要声明成为抽象类。当然,也是用”abstract”关键字来定义。

abstract class Demo{

abstract function fun1();

abstract function fun2();

......

}

抽象类一般是用来继承的。不能直接使用。使用,你想怎么直接使用。并没有实体存在啊。

定义抽象类就相当于是定义了一种规范。

子类必须遵守这种规范。而且子类必须把抽象类中的所有方法全部实现。

 

 

我们来说一下什么是接口:

接口的意思就是说,指定了一个实现该接口的类必须实现的一系列方法。

接口是一种特殊抽象类。接口里面不能声明变量,接口里面的所有方法必须声明为抽象方法,但是他不必用abstract关键字去专门定义。他声明了方法,本身就是抽象方法。接口里面所有成员都是public权限的。

声明一个接口的关键字是interface

接口的声明:

interface One{

public function fun1();

public function fun2();

}

接口也是一种规范,它是其他正常类去实现的一种规范。接口还可以继承接口。也是用rextends关键字。

 

interface Two extends One{

public function fun3();

public funciton fun4();

}

我们说了接口是去实现的,那么必然也有一个关键字,就是implments关键字。

class Three implments One

{

实现接口里面的全部方法。然后就可以去实例化对象了。

}

 

注意接口是一种规范。接口可以继承接口。接口用implments关键字来实现。注意就是接口里面不能声明变量。

我们知道类不可以多继承。但是接口可以多实现。

class four implments 接口1,接口2,接口3

{

  必须把接口中的所有方法全部实现了才可以实例化对象。

}

 

php还可以在继承类的同时去实现多个接口。

class four extends 类名 implments 接口1,接口2....

{

必须把接口中的所有方法全部实现才可以实例化对象。

}

0 0
原创粉丝点击