所谓面向对象就是何时什么东西作什么,咱们设计类的时候须要想的就是怎么作的内容,那么怎么样的一个类才算是符合OOP的思想呢,答案是:这个类写好以后,在使用的过程当中,能准确的表明一个事物,在书写的时候代码要和思惟描述一致,即这个东西作什么。
那怎么开始设计一个合格的类呢,一开始就写class{}的都错了,正确的是什么都不写,而是假设这个类已经存在,这个对象已经存在,各类属性方法都已经有了,在这个彻底的假设下想象下这个对象应该怎么用,例如咱们制做一个缩略图的类,咱们但愿封装成一个类,方便下次使用,咱们首先须要明确对象是什么它会作什么,要制做缩略图本质操做是缩小图片并输出,这里被操做的是图片,那么对象就是图片,因为网站上的图片不是惟一的咱们得告诉这是那张图片,这就能够假设下这个类已经存在,一开始就得声明是那张图片,例如$simg = new simg("1.jpg");那么,一张图片应该有哪些属性? 在制做缩略图的时候,咱们最关心的应该是 宽,高,类型,并且这三项对一张图片而言是确定的,这意味着这个对象必定有这些属性,$simg->width,$simg->height,$simg->type,而且这些属性一开始就能够读取的到的,
1 $simg = new simg("1.jpg"); 2 echo $simg->width; 3 echo $simg->height; 4 echo $simg->type; 5 //这个对象,应该能够这样操做。
根据oop的思想的原则,若是对象的属性被改变,对象应当也会发生相应的改变,这就意味着咱们能够给它赋值,取得对象的宽度,高度,计算后(好比按比例缩小),从新赋值回去。咱们本质是要制做一张图片的缩略图,也就是生成一张新的图片,改变它以后,接下来要作的事情就应该是把这个改变过的图片存起来了,存起来是一个过程,因此它会是一个方法。 例如 $simg->save(),考虑到要换一个地方存。至少要改一个名字吧, 也就是说在使用的时候,这个对象应该是这样描述的,图片 保存到 …… 这意味着,这个方法,有一个参数,就是保存到哪。
$simg = new simg("1.jpg");//实例化 $simg->width = 200;//设置宽度 $simg->height = 200;//设置高度 $simg->save("2.jpg");//保存到2.jpg
在使用这个类的时候思惟描述和写出来的代码应当彻底一致,这里的思惟描述出现了一个小问题,可能会产生不符合oop思惟原则的误导,这里不符合面向对象的是:对象属性从新赋值 原图的大小为何没有发生变化,变化的是另存出来的,也就是说这个对象实际上是php内存中源对象的复制品,咱们改变了复制品的大小并保存了下来,因此图片被真正改变以前图片的属性应当是只读的,改写是无效的, 因此,若是以原图作为对象来描述的话。这样描述应该更准确:图片 改变大小后 另存为 。而原图的大小是没有发生改变的,改变大小是一个过程,这意味着这也是一个方法,
//这个类,用起来应该是这样的。 //实例化一张图片 $simg = new simg("1.jpg"); //读取图片宽高计算比例 $simg->width $simg->height //图片使用指定的宽高另存为…… $simg->size(200,200)->save("2.jpg");
这是以原图作为对象的角度来描述的,尽管是不存在的一个类,但它的用法必须事先存在,而且符合oop的思想原则,即这是个什么东西,它能够作些什么。若是从另外的角度来思考呢,以即将被输出的图片做为对象呢,那么这个对象建立出来的时候它应该是空的,而后它必须以某张原图为基准,而后调整它的大小,再把它保存下来,
//按这个思路描述。代码应该是这个样子 $simg = new simg(); //一开始是空的 echo $simg->width; //确定是 0 $simg->load("1.jpg"); //以一张图为基准 echo $simg->width; //没改过,是原图大小 //改变大小 $simg->width = 200; $simg->height = 200; $simg->save("2.jpg"); //保存起来
此时看起来还不太明显
下面会更好:
$simg = new simg("2.jpg"); //一开始是空的,指定一个文件名 $simg->load("1.jpg"); //以一张图为基准 //改变大小 $simg->width = 200; $simg->height = 200; $simg->save(); //保存起来
这样会更明显一些,实例化一个缩略图,但它还不存在,直到保存之后它才存在于硬盘中 。php
在此咱们先按照第一种方式以原图为对象的角度建立这个类,根据上面的分析以下:网络
<?PHP class simg { public $width = 0; public $height = 0; public function __construct($img) { } public function size($width, $height) { } public function save($path) { } }
以后再根据对每一个方法每一个属性的要求,填上里面的代码,一开始就必须知道文件的高度,宽度,因为php处理不一样类型的图片使用的函数不一样,咱们在这里不得不知道文件类型是多少。以决定用哪一个函数 设计类的时候,才是思考“怎么作”的时候,要在实例化以后,立刻知道宽高。必定是在构造函数里完成的,只有构造函数会在类实例化的时候执行,这里咱们可使用 getimagesize 函数,取得文件的宽度,高度,类型 ,宽度和高度,咱们能够在这里,赋值给属性。这样一来,实例化图片,就获得属性的问题就解决了,那改变大小的过程呢?
<?PHP class simg { public $width = 0; public $height = 0; public function __construct($img) { $var = getimagesize($img); $this->width = $var[0]; $this->height = $var[1]; } public function size($width, $height) { } public function save($path) { } }
因为网络上经常使用的图片类型有gif jpg png 三种,其余的类型暂时不作考虑,调整大小的方法。在输出以前是什么也不作的。能够说,咱们的代码,只要知道要输出的图片是多大就能够了 可是,不一样的方法,内部变量不通用。怎么办注册全局变量容易被外部变量干扰和污染,那咱们就利用类的属性来保存。新加两个属性这里暂定为w和h,这两个属性,严格来讲不是属性,只是咱们利用属性来在方法之间传递变量而已,为了不它们在类的外部被访问和修改咱们在定义的时候使用关键字私有来进行访问限制,private $w = 0;private $h = 0;
public function size($width, $height) { $this->w = $width; $this->h = $height; }
public $width = 0; public $height = 0; public $path = ''; public $type = 0; private $w = 0; private $h = 0; public function __construct($img) { $var = getimagesize($img); $this->width = $var[0]; $this->height = $var[1]; $this->path = $img; $this->type = $var[2]; }
//按这个类的编写方式。。使用方法应该是这样 $simg = new simg("1.jpg"); //读取宽高并计算 $simg->width //设置大小 $simg->size(200, 200); //保存到 $simg->save("2.jpg");
public function size($width, $height) { $this->w = $width; $this->h = $height; return $this; }
返回当前的对象,这样就能够用图片 使用(这个)大小,另存为(这里)$simg->size(200, 200)->save("2.jpg");这样一个符合oop思想的类封装完成了。