PHP学习(4)

来源:互联网 发布:java现在的就业前景 编辑:程序博客网 时间:2024/05/22 00:37
本文是我边学PHP边写的学习研究,希望对于需要的人有所帮助。

PHP面向对象

基本使用:

<?phpdate_default_timezone_set("PRC");class NbaPlayer{    // 类的属性的定义    public $name="Jordan";// 定义属性    public $height="198cm";    public $weight="98kg";    public $team="Bull";    public $playerNumber="23";    // 默认的构造函数,在对象被实例化的时候自动调用    /*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";    }    // 类的方法的定义    public function run() {        echo "Running\n";    }    public function jump(){        echo "Jumping\n";    }    public function dribble(){        echo "Dribbling\n";    }    public function shoot(){        echo "Shooting\n";    }    public function dunk(){        echo "Dunking\n";    }    public function pass(){        echo "Passing\n";    }}/** * 1. 类实例化为对象时使用new关键字,new之后紧跟类的名称和一对括号。 * 2. 使用对象可以像使用其他值一样进行赋值操作 */$jordan = new NbaPlayer("Jordan", "198cm", "98kg", "Bull", "23");// 访问对象的属性使用的语法是->符号,后面跟着属性的名称echo $jordan->name."\n";// 调用对象的某个方法使用的语法是->符号,后面跟着方法的名称和一对括号$jordan->run();$jordan->pass();$james = new NbaPlayer("James", "203cm", "120kg", "Heat", "6");echo $james->name."\n";// 当对象变量被赋值为Null的时候,对象的析构函数会被自动调用// 同一个类的其他对象不受影响$james = null; echo "From now on James will not be used anymore.\n";// 当程序执行结束时,所有类的对象的析构函数都会自动被调用?>

引用:

// 当对象变量被赋值为Null的时候,对象的析构函数会被自动调用// 同一个类的其他对象不受影响$james1 = $james; // 引用赋值操作会产生对象的一个新的引用$james2 = &$james; // 使用&的引用赋值操作不会产生对象的一个新的引用$james = null; 

引用

继承:

<?phpdate_default_timezone_set("PRC");/** * 继承 * 1. 定义人类 * 2. 让NbaPlayer继承人类 * 3. PHP中类不允许同时继承多个父类,也就是extends后面只能跟一个父类名称,这个特性被称为PHP的单继承特性 */class Human{    public $name;    public $height;    public $weight;    public function eat($food){        echo $this->name . "'s eating ". $food. "\n";    }}// extends关键字用于说明该类继承自某个父类class NbaPlayer extends Human{    // 类的属性的定义    public $team="Bull";    public $playerNumber="23";    private $age="40"; // private 类型的属性不能被对象外部访问,但是可以在对象内部使用    // 默认的构造函数,在对象被实例化的时候自动调用    /*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";    }    // 类的方法的定义    public function run() {        echo "Running\n";    }    public function jump(){        echo "Jumping\n";    }    public function dribble(){        echo "Dribbling\n";    }    public function shoot(){        echo "Shooting\n";    }    public function dunk(){        echo "Dunking\n";    }    public function pass(){        echo "Passing\n";    }}/** * 1. 类实例化为对象时使用new关键字,new之后紧跟类的名称和一对括号。 * 2. 使用对象可以像使用其他值一样进行赋值操作 */$jordan = new NbaPlayer("Jordan", "198cm", "98kg", "Bull", "23");// 访问对象的属性使用的语法是->符号,后面跟着属性的名称echo $jordan->name."\n";// 调用对象的某个方法使用的语法是->符号,后面跟着方法的名称和一对括号$jordan->run();$jordan->pass();$jordan->eat("apple"); // 只要是Human类的子类的对象,就可以调用eat方法?>

访问权限:
访问权限

 private $age="40"; // private 类型的属性不能被对象外部访问,但是可以在对象内部使用 public function getAge(){        echo $this->name . "'s age is " . ($this->age - 2) . "\n";    } protected $height; // 只有自身和子类可以访问到

static关键字:

 public static $president="David Stern";    public static function changePresident($newPrsdt){        static::$president = $newPrsdt; // self用于表示当前类,"::"操作符用于访问类的静态成员        // static关键字也可以用于访问当前类的静态成员        // echo $this->age . "\n"; // 不能在静态方法中使用this伪变量,也不能用对象的->方式调用静态成员        echo parent::$sValue . "\n"; // parent用于表示父类,可以用于访问父类的静态成员    }    // 类名加“::”可以访问类的静态成员// 静态成员不需要实例化就可以访问echo "The president is ". NbaPlayer::$president. "\n";NbaPlayer::changePresident("Adam Silver");echo "The president is changed to ". NbaPlayer::$president. "\n";

final关键字:

 <?phpdate_default_timezone_set("PRC");/** * 重写和Final * 1. 子类中编写跟父类完全一致的方法可以完成对父类方法的重写 * 2. 对于不想被任何类继承的类可以在class之前添加final关键字 * 3. 对于不想被子类重写(overwrite, 修改)的方法,可以在方法定义前面添加final关键字 */class BaseClass {   public function test() {       echo "BaseClass::test() called\n";   }   public function moreTesting() {       echo "BaseClass::moreTesting() called\n";   }}class ChildClass extends BaseClass {  // 重写时参数不一定要跟父类完全一致   public function moreTesting($tmp=null) {       echo "ChildClass::moreTesting() called\n";   }}// Results in Fatal error: Cannot override final method BaseClass::moreTesting()$obj = new ChildClass();$obj->moreTesting();?>

数据访问:

<?phpdate_default_timezone_set("PRC");/** * 数据访问补充 * 1. parent关键字可以用于调用父类被重写的类成员 * 2. self关键字可以用于访问类自身的成员方法,也可以用于访问自身的静态成员和类常量;不能用于访问类自身的属性;访问类常量时不用在常量名称前面加$符号 * 3. static关键字用于访问类自身定义的静态成员,访问静态属性时需要在属性名前面添加$符号 */class BaseClass {   public function test() {       echo "BaseClass::test() called\n";   }   public function moreTesting() {       echo "BaseClass::moreTesting() called\n";   }}class ChildClass extends BaseClass {  public $height="198cm";  private static $sValue = "static value";  const CONST_VALUE = 'A constant value';  public function moreTesting() {       echo "ChildClass::moreTesting() called\n";       parent::moreTesting(); // parent关键字可以访问父类被重写的成员       // step 3 self关键字可以访问该类自身的其他成员       self::called();       // step 4 self关键字可以访问该类定义的常量       echo "CONST_VALUE: " . self::CONST_VALUE."\n";       // 常量不能被赋值修改       // self::CONST_VALUE = 11;       // step 5 static关键字可以访问静态成员,当调用静态属性时记得加$符号       echo "sValue: " . static::$sValue."\n";  }  // step 3  public function called(){    echo "ChildClass::called() called\n";  } }// Results in Fatal error: Cannot override final method BaseClass::moreTesting()$obj = new ChildClass();$obj->moreTesting();?>

接口:

<?phpdate_default_timezone_set("PRC");/** * 接口 * 1. 接口的基本概念和基本使用方法 * 2. 接口里面的方法没有具体的实现 * 3. 实现了某个接口的类必须提供接口中定义的方法 * 4. 不能用接口创建对象,但是能够判断某个对象是否实现了某个接口 * 5. 接口可以继承接口(interface extends interface) * 6. 接口中定义的所有方法都必须是公有,这是接口的特性。 */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";  }}// step1 不同的类可以实现同一个接口,定义接口方法的不同实现$man = new Human();$man->eat("Apple");$monkey = new Animal();$monkey->eat("Banana");// step2 尝试删除Human的eat方法并运行// 实现了某个接口的类必须提供接口中定义的方法// step3 不能用接口创建对象,但是能够判断某个对象是否实现了某个接口//$eatObj = new ICanEat();var_dump($man instanceof ICanEat); // 判断某个对象是否实现了某个接口// step 4 接口可以继承接口interface ICanPee extends ICanEat {  public function pee();}class Human1 implements ICanPee{  public function pee(){}}?>

多态:

<?phpdate_default_timezone_set("PRC");/** * 多态 * 1. 只要某个对象实现了接口(instanceof),就可以直接在对象上调用接口的方法 */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"); // 不需要知道到底是Human还是Animal,直接吃就行了  }else{    echo "Can't eat!\n";  }}$man = new Human();$monkey = new Animal();// 同样的代码,传入接口的不同实现类的时候,表现不同。这就是为什么成为多态的原因。eat($man);eat($monkey);?>

抽象类:

<?phpdate_default_timezone_set("PRC");/** * 抽象类 * 1. 抽象类允许类里面的部分方法暂时没有具体实现,这些方法我们成为抽象方法 * 2. 一旦类里面有抽象方法,这个类就必须是抽象类 * 3. 抽象类跟接口一样,不能直接实例化为对象 */// 抽象类前面以abstract关键字开始abstract class ACanEat {   // 没有实现的方法需要设定为抽象方法   // 抽象方法需要在子类中实现    abstract public function eat($food);   public function breath(){      echo "Breath use the air.\n";   }}// Human类实现了ICanEat接口class Human extends ACanEat {   // 跟Animal类的实现是不同的  public function eat($food){    echo "Human eating " . $food . "\n";  }}// Animal类实现了ICanEat接口class Animal extends ACanEat {  public function eat($food){    echo "Animal eating " . $food . "\n";  }}$man = new Human();$man->eat("Apple");$man->breath(); // 和Animal共用了抽象类ICanEat的breath方法$monkey = new Animal();$monkey->eat("Banana");$monkey->breath();?>

魔术方法:

<?phpdate_default_timezone_set("PRC");/** * 魔术方法1 * 1. 当对象被当做String使用时,__tostring()会被自动调用 * 2. 当对象被当成方法调用时,__invoke()会被自动调用 */class MagicTest{  public function __tostring(){    return "This is the Class MagicTest.\n";  }  public function __invoke($x){    echo "__invoke called with parameter " . $x . "\n";  }}$obj =  new MagicTest();echo $obj;$obj(5);?>

魔术方法

<?phpdate_default_timezone_set("PRC");/** * 魔术方法2之方法重载 * 1. 当对象访问不存在的方法名称时,__call()方法会被自动调用 * 2. 当对象访问不存在的静态方法名称时,__callStatic()方法会被自动调用 */class MagicTest{  public function __tostring(){    return "This is the Class MagicTest.\n";  }  public function __invoke($x){    echo "__invoke called with parameter " . $x . "\n";  }  public function __call($name, $arguments){    echo "Calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";  }  public static function __callStatic($name, $arguments){    echo "Static calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";  }}$obj =  new MagicTest();$obj->runTest("para1", "para2");MagicTest::runTest("para3","para4");?>

魔术方法

<?phpdate_default_timezone_set("PRC");/** * 魔术方法3之属性重载 * 1. 在给不可访问属性赋值时,__set() 会被调用。 * 2. 读取不可访问属性的值时,__get() 会被调用。 * 3. 当对不可访问属性调用 isset() 和empty()时,__isset() 会被调用。 * 4. 当对不可访问属性调用 unset() 时,__unset() 会被调用 */class MagicTest{  public function __tostring(){    return "This is the Class MagicTest.\n";  }  public function __invoke($x){    echo "__invoke called with parameter " . $x . "\n";  }  public function __call($name, $arguments){    echo "Calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";  }  public static function __callStatic($name, $arguments){    echo "Static calling " . $name . " with parameters: " . implode(', ', $arguments) . "\n";  }  // 通过这两个方法可以实现动态的对象属性  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 . "\n";$obj->name = "Name Value";echo '$obj->name is set? '. isset($obj->name) . "\n";echo '$obj->name is empty?' . empty($obj->name) . "\n";unset($obj->name);?>
<?phpclass nbaPlayer{    public $name;    function __clone(){        $this->name='TBD';    }}$james=new nbaPlayer();$james2=clone $james;//没有__clone,james2是新的实例,但属性值相同;有了__clone,james2的$name值是'TBD'
0 0