前言:
今天因为Android服务端要用到PHP,之前一直用的是JSP,这才花了几个小时学习PHP的基础,然而PHP基础知识点中,面向对象基础花了半个钟头去学习,因为之前学过C++,Java,C#,Object,所以当学习PHP的基础时也容易多了,当然要思考的东西也多了,因为要比较他它们之间的不同点。
进入主题:
在这里我会根据自己所学的列出PHP面向对象的基础知识点,也会附上例子。
一、类的实例化和调用普通属性和方法
<?php
class People {
// 类的属性的定义
public $name = "Jordan";
// 类的方法的定义
public function run() {
echo "Running\n";
}
public function jump() {
echo "Jumping\n";
}
}
$people = new People ();
// 访问对象的属性使用的语法是->符号,后面跟着属性的名称
echo $people->name . "\n";
// 调用对象的某个方法使用的语法是->符号,后面跟着方法的名称和一对括号
$people->run ();
?>
// 默认的构造函数,在对象被实例化的时候自动调用
function __construct() {
print "In NbaPlayer constructor\n";
}
// 构造函数通常用于初始化对象的属性值
function __construct($name, $height, $weight, $team, $playerNumber) {
print $name . ";" . $height . ";" . $weight . ";" . $team . ";" . $playerNumber . "\n";
$this->name = $name; // $this是php里面的伪变量,表示对象自身
$this->height = $height; // 通过$this可以设置对象的属性值
$this->weight = $weight;
$this->team = $team;
$this->playerNumber = $playerNumber;
}
// 析构函数,用于清理程序中使用的系统资源,比如释放打开的文件等等
// 析构函数在该对象不会再被使用的情况下自动调用
function __destruct() {
print "Destroying " . $this->name . "\n";
}
$james = new NbaPlayer ( "James", "203cm", "120kg", "Heat", "6" );
// 引用赋值操作会产生对象的一个新的引用
$james1 = $james;
// 使用&的引用赋值操作不会产生对象的一个新的引用
$james2 = &$james;
// 当对象变量被赋值为Null的时候,对象的析构函数会被自动调用
$james = null;
1.public的类成员可以被自身、子类和其他类访问。
2.protected的类成员只能被自身和子类访问。
3.private的类成员只能被自身访问。
4.无默认类型。
五、静态成员
1.静态属性用于保存类的公有数据。
2. 静态方法里面只能访问静态属性。
3. 静态成员不需要实例化对象就可以访问。
4. 类内部,可以通过self或者static关键字访问自身的静态成员。
5. 可以通过parent关键字访问父类的静态成员。
6. 可以通过类名称在外部访问类的静态成员。
private $age = "40";
public static $president = "David Stern";
// self用于表示当前类,"::"操作符用于访问类的静态成员
// static关键字也可以用于访问当前类的静态成员
static::$president ;
// 不能在静态方法中使用this伪变量,也不能用对象的->方式调用静态成员
echo $this->age;
// parent用于表示父类,可以用于访问父类的静态成员
echo parent::$sValue;
六、数据访问补充
1. parent关键字可以用于调用父类被重写的类成员。
2. self关键字可以用于访问类自身的成员方法,也可以用于访问自身的静态成员和类常量;不能用于访问类自身的属性;访问类常量时不用在常量名称前面加$符号。
3. static关键字用于访问类自身定义的静态成员,访问静态属性时需要在属性名前面添加$符号。
七、重写和Final
1. 子类中编写跟父类完全一致的方法可以完成对父类方法的重写。
2. 对于不想被任何类继承的类可以在class之前添加final关键字。
3. 对于不想被子类重写(overwrite, 修改)的方法,可以在方法定义前面添加final关键字。
八、继承(实现),抽象类,接口(多态)
她跟Java,C#类似,只能单继承,多实现,继承的其中一条好处就是复用,当然和多态也是密不可分的,因为要体现多态,就得重写方法,也就得用到继承(实现);抽象类是对接口的再次抽象的升华,更抽象!在PHP(Java,C#)中类只能单继承,多实现,接口可以实现多个接口,但是C++的类到是可以多继承。
interface ICanEat {
public function eat($food);
}
// Human类实现了ICanEat接口
class Human implements ICanEat {
// 跟Animal类的实现是不同的
public function eat($food) {
echo "Human eating " . $food . "\n";
}
}
// Animal类实现了ICanEat接口
class Animal implements ICanEat {
public function eat($food) {
echo "Animal eating " . $food . "\n";
}
}
function eat($obj) {
if ($obj instanceof ICanEat) {
$obj->eat ( "FOOD" );
} else {
echo "Can't eat!\n";
}
}
$man = new Human ();
$monkey = new Animal ();
// 同样的代码,传入接口的不同实现类的时候,表现不同。这就是为什么成为多态的原因。
eat ( $man );
eat ( $monkey );
?>
九.对象的扩展
<?php
/**
* 1. 当对象被当做String使用时,__tostring()会被自动调用
* 2. 当对象被当成方法调用时,__invoke()会被自动调用
*/
class MagicTest {
public function __tostring() {
return "This is the Class MagicTest";
}
public function __invoke($x) {
echo "__invoke called with parameter " . $x";
}
}
$obj = new MagicTest ();
echo $obj;
$obj ( 5 );
?>
<?php
/**
* 1. 在给不可访问属性赋值时,__set() 会被调用。
* 2. 读取不可访问属性的值时,__get() 会被调用。
* 3. 当对不可访问属性调用 isset() 和empty()时,__isset() 会被调用。
* 4. 当对不可访问属性调用 unset() 时,__unset() 会被调用
*/
class MagicTest{
public function __tostring(){
return "This is the Class MagicTest;
}
public function __invoke($x){
echo "__invoke called with parameter " . $x;
}
public function __call($name, $arguments){
echo "Calling " . $name . " with parameters: " . implode(', ', $arguments);
}
public static function __callStatic($name, $arguments){
echo "Static calling " . $name . " with parameters: " . implode(', ', $arguments);
}
// 通过这两个方法可以实现动态的对象属性
public function __get($name){
return "Getting the property " . $name;
}
public function __set($name, $value){
echo "Setting the property " . $name . " to value ". $value. "\n";
}
public function __isset($name){
echo "__isset invoked\n";
return false;
}
public function __unset($name){
echo "unsetting property " . $name;
}
}
$obj = new MagicTest();
echo $obj->name;
$obj->name = "Name Value";
echo '$obj->name is set? '. isset($obj->name);
echo '$obj->name is empty?' . empty($obj->name)";
unset($obj->name);
?>
