面向对象(Object-Oriented)

面向对象

  • 面向对象,即我们以对象为核心去实现我们的目的,对象顾名思义:万物皆对象,一个人,一条狗...
  • 当我们通过对象处理一些事情时,会让我们的代码清晰明了,内部高聚合,对外低耦合,即封装的思想
  • 相比面向过程,面向对象会让我们的代码更加精简,更具有灵魂性,同时也提高了代码的复用性

###下面通过PHP来讲解(实例化对象) * * *
- 面向对象,有对象必然会引入类,对象是类的实例化,当我们定义一个类,比如‘人’,那么具体到男人、女人...那便是实例化对象了 - 其定义如下:
<?php
  class Humen {
    public $name = "熔岩巨兽";              //定义共有变量
    public function eat($food){             //定义共有方法
      echo $this->name."'s eating ".$food;  //this是man实例化对象(伪变量)
    }
  }
  
  $man = new Humen();                       //通过new关键字实例化一个对象,即通过Humen类实例化出一个对象,存放到$man变量中
  echo $man->name."\n";                     //对象通过->调用类成员(属性、方法)
  $man->eat('apple');
?>

构造函数



- 当我们想要在实例化对象时,定义我们的属性和方法时,我们可以引入构造函数,这样我们便可以灵活定义属性、方法 - 其定义如下:(注:构造函数是在对象实例化时自动被调用一次,每次对象实例化都会调用一次)
<?php
  class Humen {
    public $name = "熔岩巨兽";
    public function eat($food){
      echo $this->name."'s eating ".$food;
    }
    function __construct($name, $sex, $age){      //__construct定义构造函数(双下划线),通过参数传入对象实例化时的属性
      echo $this->name = $name."\n";
      echo $this->sex = $sex."\n";
      echo $this->age = $age."\n";
    }
  }
  
  $man = new Humen("剑圣", "男", "18");           //对象实例化时传入参数
  echo $man->name."\n";
  $man->eat('apple');
?>

析构函数



- 析构函数当变量被释放后,程序运行完后会自动调用 - 由此可见,其一般用于变量释放,对象销毁等方面(注:析构函数若遇到变量释放、置空,其会被提前调用,即程序运行完毕前) - 其定义如下:
<?php
  class Humen {
    public $name = "熔岩巨兽";
    public function eat($food){
      echo $this->name."'s eating ".$food."\n";
    }
    function __construct($name, $sex, $age){
      echo $this->name = $name."\n";
      echo $this->sex = $sex."\n";
      echo $this->age = $age."\n";
    }
    function __destruct(){                       //通过__destruct来定义析构函数
    	echo "德玛西亚";
    }
  }
  
  $man = new Humen("剑圣", "男", "18");
  echo $man->name."\n";
  $man->eat('apple');
?>

注:-若$woman=$man$man=null,那么析构函数不会被调用,因$woman还指向Humen的实例化对象,对象并未销毁,所以析构并未执行,要等程序结束才会被调用
-若$woman=&$man,则会执行析构函数,因为这属于引用赋值,他俩公用一个地址,共同指向一个对象,其中一个变量销毁,那对象就销毁了,析构函数会被立即调用

继承



- 当我们定义一些类时,他们之间会有相同的属性和方法,这样定义的过程中便会重复定义 - 我们可以定义一个父类,让其拥有这些共有属性 - 让其他拥有相同属性、方法的类去继承父类 - 其定义如下
<?php
  class Humen {
    public $name = "熔岩巨兽";
    public function eat($food){
      echo $this->name."'s eating ".$food."\n";
    }
    function __construct($name, $sex, $age){
      echo $this->name = $name."\n";
      echo $this->sex = $sex."\n";
      echo $this->age = $age."\n";
    }
    function __destruct(){
    	echo "德玛西亚";
    }
  }

  class SmallHumen extends Humen{      //extends关键字定义 继承,SmallHumen子类继承了Humen父类
        
  }
  
  $man = new Humen("剑圣", "男", "18");
  echo $man->name."\n";
  $man->eat('apple');
  $smallHumen = new SmallHumen("德莱文", "男", "20");
  echo $smallHumen->name;
?>

访问权限 public,protected,private



- public,公共属性、方法,可以被自身、子类调用,也可以在类的外部调用
<?php
class Man {
     public $kl = "1";
     public function eat(){
         echo "I 'm Eat";
     }
  }
class Dog {
     public $kl = "2";
     public function eat(){
          echo "Dog 's Eat";
          echo $this->kl;        //类内部调用
     }
  }
class SmallDog extends Dog{     //extends关键字继承
      public function eat(){
        echo $this->kl;         //子类调用
      }
  }
  $man = new Man();
  $dog = new Dog();
  $sdog = new SmallDog();
  $man->eat();                  
  $dog->eat();
  echo $dog->kl;                //类外部调用
  echo $man->kl;
  $sdog->eat();
?>
  • protected, 受保护的属性、方法,自身、子类可以调用,类的外部不可以调用
<?php
class Man {
     public $kl = "1";
     public function eat(){
         echo "I 'm Eat";
     }
  }
class Dog {
     protected $kl = "2";
     public function eat(){
          echo "Dog 's Eat";
          echo $this->kl;        //类内部调用
     }
  }
class SmallDog extends Dog{     //extends关键字继承
      public function eat(){
        echo $this->kl;         //子类调用
      }
  }
  $man = new Man();
  $dog = new Dog();
  $sdog = new SmallDog();
  $man->eat();                  
  $dog->eat();
  echo $dog->kl;               //类外部调用,会出错
  echo $man->kl;
  $sdog->eat();
?>
  • private,私有成员,只可以自身调用
<?php
class Man {
     public $kl = "1";
     public function eat(){
         echo "I 'm Eat";
     }
  }
class Dog {
     private $kl = "2";
     public function eat(){
          echo "Dog 's Eat";
          echo $this->kl;        //类内部调用
     }
  }
class SmallDog extends Dog{     //extends关键字继承
      public function eat(){
        echo $this->kl;         //子类调用,会出错
      }
  }
  $man = new Man();
  $dog = new Dog();
  $sdog = new SmallDog();
  $man->eat();                  
  $dog->eat();
  echo $dog->kl;               //类外部调用,会出错
  echo $man->kl;
  $sdog->eat();
?>

static关键字



  • 当有多个类继承了同一个类,通过其中一个子类改变父类属性时,会同时影响其他子类,即其他子类继承的属性也会变化
  • 但是由下面一段代码看,并不是这样,这不是我们所要
<?php

  class Animal{
    public $scale = "奔波霸";
    public function changeCon ($name){
      $this->scale = $name;
    }
  }
  class Man extends Animal {
     public function eat(){

     }
  }
  class Dog extends Animal {
     public function eat(){

     }
  }

  $man = new Man();
  $dog = new Dog();
  $man->changeCon("霸波奔");    //改变了父类Animal里scale的值
  echo $dog->scale;             //对于$dog对象,scale并未改变
?>

  • 引入static关键字,实现属性全局化,即一个子类改变父类的属性,其他子类继承到的属性也会变化
<?php

  class Animal{ 
    public static $scale = "奔波霸";             //通过static关键字调用静态属性,方法
    public static function changeCon ($name){
      self::$scale = $name;                     //通过self\static,::操作符调用静态属性,记得静态变量前加 $
    }
  }
  class Man extends Animal {                    //extends关键字继承
     public function eat(){

     }
  }
  class Dog extends Animal {
     public function eat(){

     }
  }

  Man::changeCon("霸波奔");                    //通过类和操作符::,直接调用静态方法(继承了父类的changeCon方法)
  echo Dog::$scale;                            //输出后发现其他子类继承的属性也发生了变化,由此可见static将变量全局化了
?>

方法的重写(override)



- 子类里具有与父类相同名字方法 - 参数可以不同
<?php
  class Animal{
    public  $scale = "oop";
    public  function changeCon (){      //父类里的changeCon方法
      echo "孙爷爷";
    }
  }
  class Man extends Animal {
     public function eat(){
        
     }
     public  function changeCon (){    //与父类里相同名字的方法
       echo "玉帝老儿";                   
    }
  }
  class Dog extends Animal {
     public function eat(){
         
     }
  }
  $man = new Man();
  $dog = new Dog();
  $man->changeCon();                    //输出后,发现子类对父类方法重写了

?>

final关键字



- 在类、方法前加上final关键字后,类不可以被继承,方法不可以被重写 - final 不可以加到属性前面
<?php
  final class Animal{                          //final使得子类不能继承父类的方法 may not inherit
    public  $scale = "oop";
    final public  function changeCon (){       //final使得子类不能重写父类的方法 Cannot override
      echo "孙爷爷";
    }
  }
  class Man extends Animal {                   //子类不可以再继承父类(final关键字的作用)
     public function eat(){
        
     }
     public  function changeCon (){            //与父类里相同名字的方法,这里子类对父类方法的重写会失败
       echo "玉帝老儿";                   
    }
  }
  class Dog extends Animal {
     public function eat(){
         
     }
  }
  $man = new Man();
  $dog = new Dog();
  $man->changeCon(); 

?>

数据访问



- parent:: - self::
<?php
    class Animal{                          
    public  $scale = "oop";
    final public  function changeCon (){       
      echo "孙爷爷";
    }
  }
  class Man extends Animal {                  
     public function eat(){
        parent::changeCon();                 //通过parent::,访问父类的方法
        self::changeCon();                   //通过self::,访问子类的方法
     }
     public  function changeCon (){            
       echo "玉帝老儿";                   
    }
  }
  class Dog extends Animal {
     public function eat(){
         
     }
  }
  $man = new Man();
  $dog = new Dog();
  $man->eat(); 

?>

接口(interface)



接口的定义

  • interface关键字定义接口
  • implements关键字实现接口
  • 接口里的方法不需要具体实现
  • 类通过implements实现接口后要实现方法,方法名必须与接口里的方法名一致
  • 接口不可以直接实例化,必须通过类实现,然后类再去实例化
<?php

  interface ICanEat {                   //定义接口
    public function eat();              //定义方法,不需要实现
  }
  class Man implements ICanEat {        //实现接口
    public function eat(){              //实现方法
      echo "I 'm a man";
    }
  }
  class Dog implements ICanEat {        //实现接口
    public function eat(){              //实现方法
      echo "I 'm a dog"; 
    }
  }
  
  $man = new Man();
  $dog = new Dog();
  $man->eat();
  $dog->eat();
  
?>

判断是否属于实现接口的类的实例化对象(instanceOf)

<?php

  interface ICanEat {
    public function eat();
  }
  class Man implements ICanEat {
    public function eat(){
      echo "I 'm a man";
    }
  }
  class Dog implements ICanEat {
    public function eat(){
      echo "I 'm a dog";
    }
  }
  $man = new Man();
  $dog = new Dog();
  $man->eat();
  $dog->eat();
  function scale ($who){
    if($who instanceOf ICanEat){  //判断是否属于实现接口的类的实例化对象
      echo "true";
    }else{
      echo "false";
    }
  }
  scale($man);                   //调用上面的scale方法
  scale($dog);
  
?>

接口的继承

  • 通过extends关键字继承
  • 继承后要通过类实现自己、自己的方法、父接口的方法
<?php

  interface ICanEat {
    public function eat();
  }
  class Man implements ICanEat {
    public function eat(){
      echo "I 'm a man";
    }
  }
  class Dog implements ICanEat {
    public function eat(){
      echo "I 'm a dog";
    }
  }
  
  interface YouCanEat extends ICanEat {    //继承接口
    public function yEat();
  }
  class Women implements YouCanEat{        //实现接口
    public function yEat(){                //实现自己的方法
      echo  "You can eat";
    }
    public function eat(){                 //实现父接口的方法
      echo  "I can eat";
    }
  }
  $man = new Man();
  $dog = new Dog();
  $man->eat();
  $dog->eat();
  
?>

多态



- 类实现接口后,不同的实例化对象调用接口方法时,实现的结果不同即为多态

抽象类(abstract)



  • 类里的方法是全部定义好的
  • 接口里的方法是没有实现的
  • 抽象类里的方法是部分实现的
  • 对于相同的方法定义好、实现好,便于调用;不同的方法定义抽象方法,具体到某一个子类再去具体实现
<?php

abstract class Animal{                     //abstract定义抽象类
    abstract public function eat();        //未定义好方法
    public  function breath (){            //所有子类相同的方法,在父类里统一定义,然后继承
      echo "breath";
    }
  }
  class Man extends Animal {
     public function eat(){                //具体再在子类里定义,必须与抽象类里的抽象方法一致
      echo "Man eat"; 
     }
  }
  class Dog extends Animal {
     public function eat(){
        echo "Dog eat";
     }
  }
  $man = new Man();
  $dog = new Dog();
  $man->eat();
  $man->breath();
  $dog->eat();
  $dog->breath();
?>
posted @ 2016-12-28 20:02  孙凯亮  阅读(352)  评论(0编辑  收藏  举报