在前面的章节中,我们接触到了很多类似于这样的方法`类名::方法名()`。比如:我们使用`Db::name()`来获取某个数据表模型,使用`Resquest::instance()`来获取请求模型使用了`::get()`来获取单条数据模型,使用`::select()`来获取多条数据模型,使用`::destroy`来销毁数据。 ThinkPHP5大量的使用了这种可以直接使用`::`调用的方法,它们有一个很响亮的名字:静态方法。静态方法的引用,大幅提升了程序的运行效率,降低了资源的占用。在实际项目开发中,由于静态方法的优越性,我们还会大量使用。虽然本教程的前面也简单的对静态方法进行过讲解,但距离『理解』这个程度还不够。 争取通过本章的学习,能够让静态方法在我们心中留下更深的印象。 # 静态方法 为什么要有静态方法? 1. 可以降低内存的占用。 2. 提高程序的执行效率。 什么时候用静态方法? 当这个方法与具体的对象无关时。 * * * * * ##对象、类: 人是一个类,而周润发就是一个对象。 对象,我们认为是存在于现实社会的。而类呢?是存在于我们大脑中的。我们说自行车、汽车、小猫、电脑、笔记本电脑,这些其实都是描述一类具体事件的一些概念。这些概念存在我们大家的大脑中,我们把这个概念性的东西,就叫做类。 我们说『人』是一个类,是由于它代表的是一类事物。类的特点是,当我们进行交流的时候,我们想到的具体事物可能不是一个。比如,今天的任务是:找一个美女(帅哥)搭讪,那么每个人找的美女(帅哥)都会不一样。要求大家每人今天摘一片树叶回来,那么大家摘的树叶也不会一样。原因是因为,美女是指的一类人,树叶,是指的一类事物。美女:我们想像的;树叶:我们想像的。 我们说女人是一个类,因为女人这个概念存在于我们的大脑中,而孙燕姿、贾玲就是一个个对象。 ![](https://box.kancloud.cn/2016-06-20_57678335364a7.png) 当然了,我们男孩也是一个类。 ![](https://box.kancloud.cn/2016-06-20_5767833557285.png) 我们说王宝强拍的电影是个类,而王宝强拍的『天下无贼』是一个对象;我们说梦云智团队是一个类,而团队中的每个成员都是对象;我们说笔记本是个类,而你正在使用的这台笔记本则是个对象。 总结: > 类是存在于大脑中的概念,是对具体事物的抽象,并不是实体(实际存在的物体);而对象是一个实体,它具有唯一性,是具体的事物。 * * * * * ##静态方法 对于每一个河北工业大学的学生来讲,不管问我们谁:学校建校有100年了吗? 答案都是:有。 其实河北工业大学有没有100年,和问我们谁没有关系。只要是一个河北工业大的学生,就能准确的回答这个问题。 即:你只要问“河北工业大学的学生”这类人,那么答案可以确定,对于这个方法 ,我们就**可以**声明为静态方法。 而对于,”你的生日是哪天“?这些方法,由于不同的河北工业大学的学生回答的答案可能不同,那么就不能声明为静态方法。 总结(比较抽象): > 虽然我们把方法都写在了一个类中,但是却有所区别。 > 静态方法:有类,就可以被调用,与类相关联。 > 非静态方法:只有存在对象的时候,这个方法才可以被调用,与对象相关联。 简单总结: > 如果这个方法中没有用到$this(即没有使用到这个类中的内部变量),就应该声明为静态方法,以提升执行效率。 上面这句话还有另一层含义是:你完全可以不声明为静态方法,绝对不会报错,只是会影响一些执行效率罢了。 ### 原来如此 我们重复下上面的问题: 我们把河北工业大学的学生,定义为一类人,这类人,我们起名叫Hebuter,它们的共同属性除了是人,还是大学生,还是一所大学的学生。 比如我现在有一个问题:河北工业大学,建校有100年了吗? 我们想:这个问题凡是这个学校的学生,就会知道正确的答案。 我还有一个问题:你的身份证号是多少? 我们想,每个学生的答案都是唯一的,是有区别的。 那么,针对上面两个问题。在程序中,我们可以这样写: > 我们将测试代码写到```public```文件夹下的```test.php```中。 ~~~ public function test() { $Hebuter = new Hebuter; $xiaohong = $Hebuter::get('xiaohong'); // 小红 $xiaoming = $Hebuter::get('xiaoming'); // 小明 // 小红与小明回答学校是否建校100年,答案一致 var_dump($xiaohong->isSchoolMoreThan100()); var_dump($xiaoming->isSchoolMoreThan100()); // 小红和小明回答自己的身份证号码,答案不一致 var_dump($xiaohong->whatIsYouId()); var_dump($xiaoming->whatIsYouId()); } ~~~ 我们将一些和具体的对象无关、而与具体的类有关的方法,往往定义为静态方法。 比如是否建校100年,只要是Hebuter给出的答案就是一致的。 在调用静态方法时,由于并不需要确定是哪个对象,所以可以不必实例化。 而与具体的对象相关,比如这里问你的身份证是多少,那么就不能定义成静态方法。 所以上述代码可以修改为: ~~~ public function test() { // 只要是我们学校的学生,回答学校是否建校100年,答案都是一个。 var_dump(Hebuter::isSchoolMoreThan100()); $Hebuter = new Hebuter; $xiaohong = $Hebuter::get('xiaohong'); // 小红 $xiaoming = $Hebuter::get('xiaoming'); // 小明 // 小红和小明回答自己的身份证号码,答案不一致 var_dump($xiaohong->whatIsYouId()); var_dump($xiaoming->whatIsYouId()); } ~~~ 以后我们还会接触越来越多的静态方法,用的多了,自然就理解了,在这里,有个概念就可以了。 完整代码如下: ~~~ <?php class Test { public function test() { // 只要是我们学校的学生,回答学校是否建校100年,答案都是一个。 var_dump(Hebuter::isSchoolMoreThan100()); $Hebuter = new Hebuter; $xiaohong = $Hebuter::get('xiaohong'); // 小红 $xiaoming = $Hebuter::get('xiaoming'); // 小明 // 小红和小明回答自己的身份证号码,答案不一致。 var_dump($xiaohong->whatIsYouId()); var_dump($xiaoming->whatIsYouId()); } } class Hebuter { private $name; // 姓名 // 设置姓名 public function setName($name) { $this->name = $name; } // 学校是否有百年历史 static public function isSchoolMoreThan100() { return true; } // 获取ID信息 public function whatIsYouId() { if ($this->name === 'xiaohong') { return '1234567'; } if ($this->name === 'xiaoming') { return '7654321'; } return '88888888'; } // 根据名字获取Hebuter对象 static public function get($name) { $Hebuter = new Hebuter; $Hebuter->setName($name); return $Hebuter; } } // 以下是测试代码 $Test = new Test; // 实例化 $Test->test(); // 调用对象中的方法 ~~~ 访问如下地址进行测试: ![](https://box.kancloud.cn/fc83dc28a3ed5cbc7f6cfd99ddd91735_615x254.png) 好像还有一点点乱对吧,没关系,如果还乱,多找一些关于类与对象的学习资料再看看吧,这个的确是个长久的学习过程。