编程的艺术就是处理复杂性的艺术
----------------- Edsger Dijkstra
面向对象的核心内容就是一切事物皆为对象。
第一次接触面向对象的时候是java,面向对象主要的特点就是封装,继承和多态。对于面向对象的概念我也不必多说,这里我只记录一下php的面向对象的使用方法。
类的声明
和各种语言一样php也是通过class来声明类的
那么声明类需要几个注意
- 权限修饰符是可选项(public protected private 或者省略)
- class是创建类的关键字
- 类名是所需要创建类的名称,在class之后,后面是{}
- 类体必须放在{}里
下面是一个简单的类的声明,包括一个构造方法和一些getter和setter方法
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/10
* Time: 21:15
*/
class student
{
var $name;
var $age;
var $sex;
/**
* student constructor.
* @param $name
* @param $age
* @param $sex
*/
public function __construct($name, $age, $sex)
{
$this->name = $name;
$this->age = $age;
$this->sex = $sex;
}
/**
* @return mixed
*/
public function getName()
{
return $this->name;
}
/**
* @param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return mixed
*/
public function getAge()
{
return $this->age;
}
/**
* @param mixed $age
*/
public function setAge($age)
{
$this->age = $age;
}
/**
* @return mixed
*/
public function getSex()
{
return $this->sex;
}
/**
* @param mixed $sex
*/
public function setSex($sex)
{
$this->sex = $sex;
}
}
下面是一个测试的文件
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/10
* Time: 21:19
*/
//注意在这个地方,需要引用这个类文件(php的类要带个.class.php的后缀)
require_once 'Student.class.php';
echo "下面创建一个student对象";
//初始化
$stu = new Student("surine",12,"boy");
//使用
echo $stu->getName();
echo $stu->sex;
除了注意这个类需要手动引入之外其他的都很简单,和java的类似。
特殊访问方式
1.$this
this这个用法我们在java里也经常用,作用就是完成对象内部成员之间的访问。
2.::
相比this,::才是真正的强大,他可以在没有任何实例的情况下来访问类成员
那么他的格式如下
关键字::变量名/常量名/方法名
这里的关键字分为下面几种情况
1. parent : 调用父类的相关成员 (相当于java的super)
2. self:调用当前类的静态成员和常量
3. 类名:调用本类的变量常量和方法。
下面是一个演示
<?php
class animal{
const NMAE = "动物";
/**
* animal constructor.
*/
public function __construct()
{
//使用类名访问常量成员
echo "动物类:".animal::NMAE;
}
}
class Cat extends animal{
const NMAE = "猫";
/**
* Cat constructor.
*/
public function __construct()
{
echo "<br>";
//使用parent访问父类构造
echo parent::__construct();
echo "<br>";
//使用self访问自身常量成员
echo self::NMAE;
echo "<br>";
}
}
echo "类外调用:".Cat::NMAE;
new Cat();
运行结果:
运行结果PNG构造和析构
构造函数大家都知道,在面向对象语言中起着初始化的作用,php也不例外,java中构造函数必须和类同名,php也可以这样写,但是更常见的是下面这种写法
public function __construct()
{
//注意construct前面是两个下划线
}
我们知道java等语言构造方法是可以有多个的,我们称之为重载,但是php不允许这样,他通过默认参数来实现重载,我们可以给参数赋值,也可以不用这样达到了同样的一个效果。
那么我们同样知道析构函数是在对象销毁的时候执行的一个方法
function __destruct()
{
// TODO: Implement __destruct() method.
}
通常在析构方法里做一些释放资源的任务。
封装
这是面向对象的三大特点之一,封装的意思就是抽象一个类,包含一些属性,那么这些属性或者方法都有访问权限,比如说public,private,protected
继承
继承使得面向对象更加灵活,我们可以通过extends关键字来实现一个类的继承,在前面我也演示过,并且我们知道通过parent::来访问父类的方法
多态
多态顾名思义就是有多种状态,包括重载重写等
下面是一个通过接口(接口在下面讲到)实现的多态
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/11
* Time: 14:26
*/
interface Type{
public function go_Type();
}
class Type_car implements Type{
public function go_Type()
{
echo "car";
// TODO: Implement go_Type() method.
}
}
class Type_bus implements Type{
public function go_Type()
{
echo "bus";
// TODO: Implement go_Type() method.
}
}
function change($obj){
if($obj instanceof Type){
$obj->go_Type();
}else{
echo "obj不合法";
}
}
change(new Type_car());
那么这个当然是输出car。
抽象
抽象类是不能被实例化的特殊类,他是配合多态使用的,只能作为其他类的父类,使用abstract来声明
那么抽象类和普通类相似,包括成员变量和成员方法,两者区别在于,抽象类至少要包含一个抽象方法,那这个方法是没有方法体,他的方法体是在子类中实现的。
例如:
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/11
* Time: 14:11
*/
abstract class animal{
abstract function run();
abstract function eat();
}
class cat extends animal{
//必须实现其方法
function run()
{
// TODO: Implement run() method.
echo "run()";
}
function eat()
{
// TODO: Implement eat() method.
echo "eat()";
}
}
$cat = new Cat();
//调用
$cat->eat();
我们抽象一个动物方法,然后用cat类继承自它,实现其中的相关方法,然后我们可以通过对象进行调用。
接口
继承增加了类的复用性,但php和java类似也只支持单继承,那么多继承当然是使用接口实现。
接口声明如下
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/11
* Time: 14:17
*/
interface One{
const CON = "value";
function One();
}
interface Two extends One{
function Two();
}
可以看到php的接口也是interface声明,而且也支持extends
那么接口怎么使用?
require_once "MyInter.php";
class TestInter implements One,Two{
public function One(){
echo "one";
}
public function Two(){
echo "two";
}
}
$test = new TestInter();
$test->Two();
输出结果就是two
其他关键字
1.final
final意思是最终的,最后的,也就是最终版本,不允许做其他修改,如果有个类用final修饰,那么他一定不会有子类,不会被继承
2.static
static就是静态的意思,在java中也是有的,他属于类本身,但是不属于类的任何实例,它相当于储存在类中的全局变量,那么同样我们可以使用::访问
魔术方法
php中有很多以__开头的方法,比如说构造,析构,这些方法被称为魔术方法,那么下面是几个魔术方法
1.__get() __set()
这是php的getter和setter,用于赋值获取值,为外部提供的访问接口
2.__isset() __unset()
这个函数类似于isset和unset函数,如果对象中存在__isset()方法,当在类的外部使用isset函数检测对象中的私有成员属性时,就会自动调用类中的__isset()方法完成对私有成员属性的检测操作
__unset()函数是删除指定的变量,参数为要删除的变量名称
3.__call()
这个函数的作用是:当对象企图使用一个不存在的方法时,系统就会调用call函数,并且把方法名和参数都记录下来。
下面是一个例子
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/11
* Time: 14:43
*/
class Call{
var $a;
/**
* Call constructor.
* @param $a
*/
public function __construct($a)
{
$this->a = $a;
}
/**
* @return mixed
*/
public function getA()
{
return $this->a;
}
/**
* @param mixed $a
*/
public function setA($a)
{
$this->a = $a;
}
function __call($name, $arguments)
{
echo $name;
echo "<br>";
print_r($arguments);
// TODO: Implement __call() method.
}
}
$a = new Call(10);
$a->A("???");
可以看到我们最后调用了A这个方法,这个方法其实是不存在的,系统识别到,并调用了__cal方法,输出结果就是call方法体里的内容
call.PNG4.__toString()
这个方法在java中也见过,那么我们可以这样使用它
//在类里实现它
function __toString()
{
return "我是方法";
// TODO: Implement __toString() method.
}
//直接打印对象
echo $a;
得到的结果就是执行了__toString输出的内容。
如果没有这个方法将会发生致命错误
5.__autoload()
可以看到我们在之前的类导入的时候都是手动require的,这样比较麻烦也比较乱。
那么系统为我们提供了自动导入的方法,下面一个小例子演示一下
<?php
/**
* Created by PhpStorm.
* User: surine
* Date: 2017/8/11
* Time: 14:55
*/
function __autoload($name){
$file = realpath(__DIR__).'/'.$name.'.php';
if(file_exists($file))
{
require_once($file);
if(class_exists($name,false))
{
return true;
}
return false;
}
return false;
}
$test = new Call();
$test->getA();
在未实例化之前系统首先判断存不存在这个文件,然后确定导入之后才能实例化。
总结
当然面向对象不止这点东西,更多更有意思的东西在以后学习过程中研究。
网友评论