PHP 面向对象编程

PHP 面向对象编程

我们可以想象我们的宇宙由不同的对象组成,像太阳、地球、月亮等等。类似地,我们可以想象我们的汽车由轮子、方向盘、齿轮等不同的对象组成。同样地,面向对象编程概念将一切都视为对象,并使用不同的对象来实现软件。

面向对象概念

在我们深入讨论之前,先定义与面向对象编程相关的重要术语。

  • - 这是一种由程序员定义的数据类型,包含本地函数和本地数据。您可以将类看作是制造许多相同类型(或类)的对象实例的模板。

  • 对象 - 由类定义的数据结构的单个实例。您只需定义一次类,然后创建许多属于该类的对象。对象也称为实例。

  • 成员变量 - 这些是定义在类内部的变量。这些数据对类的外部是不可见的,但可以通过成员函数来访问。一旦创建了对象,这些变量就称为对象的属性。

  • 成员函数 - 这些是在类内部定义的函数,用于访问对象数据。

  • 继承 - 当一个类通过继承现有的父类函数来定义时,就被称为继承。子类将继承父类的所有或部分成员函数和变量。

  • 父类 - 被另一个类继承的类。这也称为基类或超类。

  • 子类 - 继承另一个类的类。这也称为子类或派生类。

  • 多态 - 这是面向对象的一个概念,同一个函数可以用于不同的目的。例如,函数名称保持不变,但接受不同数量的参数并可以执行不同的任务。

  • 重载 - 这是一种多态性,其中一些或所有操作符根据其参数类型具有不同的实现。类似地,函数也可以使用不同的实现进行重载。

  • 数据抽象 - 任何表示数据的方式,其中隐藏了实现细节(抽象化)。

  • 封装 - 指的是将所有的数据和成员函数封装在一起形成一个对象的概念。

  • 构造函数 - 指的是一种特殊类型的函数,当从一个类中形成对象时,会自动调用该函数。

  • 析构函数 - 指的是一种特殊类型的函数,当一个对象被删除或超出范围时,会自动调用该函数。

定义PHP类

在PHP中定义一个新类的一般形式如下:

<?php
   class phpClass {
      var var1;
      varvar2 = "constant string";

      function myfunc (arg1,arg2) {
         [..]
      }
      [..]
   }
?>
PHP

以下是每行的说明:

  • 特殊形式 class ,后面跟着你要定义的类的名称。

  • 一对大括号,内部包含任意数量的变量声明和函数定义。

  • 变量声明以特殊形式 var 开头,后面跟着一个常规的$变量名;它们也可以有初始赋值给一个常量值。

  • 函数定义看起来很像独立的PHP函数,但是它们是局部的类函数,用于设置和访问对象数据。

示例

以下是一个定义了Books类型的类的示例:

<?php
   class Books {
      /* Member variables */
      var price;
      vartitle;

      /* Member functions */
      function setPrice(par){this->price = par;
      }

      function getPrice(){
         echothis->price ."<br/>";
      }

      function setTitle(par){this->title = par;
      }

      function getTitle(){
         echothis->title ." <br/>";
      }
   }
?>
PHP

变量 $this 是一个特殊的变量,它指的是同一个对象,即它本身。

在PHP中创建对象

一旦你定义了类,你就可以创建多个属于该类类型的对象。下面是使用 new 操作符创建对象的示例。

$physics = new Books;
$maths = new Books;
$chemistry = new Books;
PHP

在这里,我们创建了三个对象,这些对象是相互独立的,它们将分别存在。接下来,我们将看到如何访问成员函数和处理成员变量。

调用成员函数

创建对象后,您将能够调用与该对象相关的成员函数。一个成员函数只能处理其相关对象的成员变量。

以下示例展示了如何通过调用成员函数为这三本书设置标题和价格。

$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );

$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );
PHP

现在你调用另一个成员函数来获取上面示例中设置的值 –

$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
PHP

这将产生以下结果−

Physics for High School
Advanced Chemistry
Algebra
10
15
7
PHP

构造函数

构造函数是一种特殊类型的函数,当对象被创建时会自动调用。因此,我们通过构造函数可以初始化许多事物。

PHP提供了一个特殊的函数称为 __construct() 来定义一个构造函数。您可以在构造函数中传递任意多个参数。

以下示例将为Books类创建一个构造函数,并在对象创建时初始化图书的价格和标题。

function __construct( par1,par2 ) {
   this->title =par1;
   this->price =par2;
}
PHP

现在我们不需要分别调用set函数来设置价格和标题。我们只需要在对象创建时初始化这两个成员变量。请查看以下示例−

$physics = new Books( "Physics for High School", 10 );
$maths = new Books ( "Advanced Chemistry", 15 );
$chemistry = new Books ("Algebra", 7 );

/* Get those set values */
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();

$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();
PHP

这将产生以下结果 −

Physics for High School
  Advanced Chemistry
  Algebra
  10
  15
  7
PHP

析构函数

类似于构造函数,您可以使用函数 __destruct() 来定义析构函数。您可以在析构函数中释放所有资源。

继承

PHP类定义可以选择性地通过使用extends子句从父类定义中继承。语法如下所示 –

class Child extends Parent {
   <definition body>
}
PHP

继承的影响是子类(或子类或派生类)具有以下特点 −

  • 自动具有父类的所有成员变量声明。

  • 自动具有与父类相同的所有成员函数,默认情况下这些函数的工作方式与父类中的函数相同。

以下示例继承了Books类,并根据需求添加了更多功能。

class Novel extends Books {
   var publisher;

   function setPublisher(par){
      this->publisher =par;
   }

   function getPublisher(){
      echo $this->publisher. "<br />";
   }
}
PHP

现在除了继承的函数之外,类Novel还保留了两个额外的成员函数。

函数重写

子类中的函数定义会覆盖父类中相同名称的定义。在子类中,我们可以修改从父类继承的函数的定义。

在下面的示例中,getPrice和getTitle函数被重写以返回一些值。

function getPrice() {
   echo this->price . "<br/>";
   returnthis->price;
}

function getTitle(){
   echo this->title . "<br/>";
   returnthis->title;
}
PHP

公共成员

除非您另行指定,类的属性和方法都是公共的。也就是说,它们可以在以下三种情况下访问:

  • 在声明该类之外的地方

  • 在声明该类的内部

  • 在实现该类的另一个类的内部

到目前为止,我们已经把所有成员都视为公共成员。如果您希望限制类的成员的可访问性,那么您可以将类成员定义为 私有受保护

私有成员

通过将成员指定为私有,您限制了它只能在声明它的类中访问。私有成员不能从继承该类的类中引用,也不能从类外部访问。

可以使用 private 关键字将类成员设置为私有成员。

class MyClass {
   private car = "skoda";driver = "SRK";

   function __construct($par) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }

   function myPublicFunction() {
      return("I'm visible!");
   }

   private function myPrivateFunction() {
      return("I'm  not visible outside!");
   }
}
PHP

当另一个类使用extends继承MyClass类时,myPublicFunction()和driver将可见。扩展的类将无法意识到或访问myPrivateFunctiondriver将可见。扩展的类将无法意识到或访问myPrivateFunction和car,因为它们被声明为私有。

保护成员

受保护的属性或方法可在声明它的类中访问,以及扩展该类的类中访问。受保护的成员在这两种类型的类之外不可用。通过在成员前面使用 protected 关键字,可以将类成员设置为受保护。

这是MyClass的另一个版本 –

class MyClass {
   protected car = "skoda";driver = "SRK";

   function __construct($par) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }

   function myPublicFunction() {
      return("I'm visible!");
   }

   protected function myPrivateFunction() {
      return("I'm  visible in child class!");
   }
}
PHP

接口

接口是为实现者提供共同的函数名称。不同的实现者可以根据自己的需求实现这些接口。可以说,接口是由开发人员实现的骨架。

从PHP5开始,可以像这样定义一个接口−

interface Mail {
   public function sendMail();
}
PHP

然后,如果另一个类实现了该接口,就像这样 –

class Report implements Mail {
   // sendMail() Definition goes here
}
PHP

常量

常量有点像变量,因为它保存一个值,但更像一个函数,因为常量是不可变的。一旦声明了一个常量,它就不会改变。

声明一个常量很简单,就像在这个版本的MyClass中做的一样−

class MyClass {
   const requiredMargin = 1.7;

   function __construct($incomingValue) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }
}
PHP

在这个类中,requiredMargin是一个常量。它使用关键字const声明,在任何情况下都不能改变为除了1.7之外的其他值。注意,常量的名称没有前导的$,和变量的名称不同。

抽象类

抽象类是不能被实例化的,只能被继承。你可以使用关键字 abstract 来声明一个抽象类,如下所示:

当继承一个抽象类时,父类声明中所有标记为抽象的方法必须由子类来定义;此外,这些方法必须具有相同的可见性。

abstract class MyAbstractClass {
   abstract function myAbstractFunction() {
   }
}
PHP

注意,在抽象类中定义的函数也必须以abstract关键字开头。在非抽象类中定义抽象函数是不合法的。

静态关键字

将类成员或方法声明为静态可以在不实例化类的情况下访问它们。声明为静态的成员不能使用实例化的类对象访问(但静态方法可以)。

尝试下面的示例 −

<?php
   class Foo {
      public static my_static = 'foo';

      public function staticValue() {
         return self::my_static;
      }
   }

   print Foo::my_static . "\n";foo = new Foo();

   print $foo->staticValue() . "\n";
?>
PHP

Final关键字

PHP 5引入了final关键字,通过在方法定义前加上final来阻止子类覆盖方法。如果类本身被定义为final,则无法被继承。

以下示例会导致致命错误:无法覆盖BaseClass::moreTesting()的final方法。

<?php

   class BaseClass {
      public function test() {
         echo "BaseClass::test() called<br>";
      }

      final public function moreTesting() {
         echo "BaseClass::moreTesting() called<br>";
      }
   }

   class ChildClass extends BaseClass {
      public function moreTesting() {
         echo "ChildClass::moreTesting() called<br>";
      }
   }
?>
PHP

调用父构造函数

不需要为子类编写全新的构造函数,我们可以通过显式调用父类的构造函数来编写子类的构造函数,并在子类实例化时进行其他必要的操作。这里是一个简单的示例:

class Name {
   var _firstName;
   var_lastName;

   function Name(first_name,last_name) {
      this->_firstName =first_name;
      this->_lastName =last_name;
   }

   function toString() {
      return(this->_lastName .", " .this->_firstName);
   }
}
class NameSub1 extends Name {
   var _middleInitial;

   function NameSub1(first_name, middle_initial,last_name) {
      Name::Name(first_name,last_name);
      this->_middleInitial =middle_initial;
   }

   function toString() {
      return(Name::toString() . " " . $this->_middleInitial);
   }
}
PHP

在这个示例中,我们有一个父类(Name),它有一个带有两个参数的构造函数,还有一个子类(NameSub1),它有一个带有三个参数的构造函数。NameSub1的构造函数通过使用::语法显式调用其父类构造函数(传递两个参数),然后设置一个额外的字段。类似地,NameSub1通过覆盖的父类函数来定义它的非构造函数toString()函数。

注意 - 构造函数可以使用与类名相同的名称进行定义。在上面的示例中已经定义了。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册