PHP5中实现多态的两种方法实例分享

多态这个概念,在Java中指的是变量可以指向的对象的类型,可是变量声明类型的子类。对象一旦创建,它的类型是不变的,多态的是变量。

在PHP5中,变量的类型是不确定的,一个变量可以指向任何类型的数值、字符串、对象、资源等。我们无法说PHP5中多态的是变量。

我们只能说在PHP5中,多态应用在方法参数的类型提示位置。

一个类的任何子类对象都可以满足以当前类型作为类型提示的类型要求。

所有实现这个接口的类,都可以满足以接口类型作为类型提示的方法参数要求。

简单的说,一个类拥有其父类、和已实现接口的身份。

通过实现接口实现多态,代码如下:

  1. <?php
  2. interface User{ // User接口
  3. public function getName();
  4. public function setName($_name);
  5. }
  6. class NormalUser implements User { // 实现接口的类.
  7. private $name;
  8. public function getName(){
  9. return $this->name;
  10. }
  11. public function setName($_name){
  12. $this->name = $_name;
  13. }
  14. }
  15. class UserAdmin{ //操作.
  16. public static function ChangeUserName(User $_user,$_userName){
  17. $_user->setName($_userName);
  18. }
  19. } //phpfensi.com
  20. $normalUser = new NormalUser();
  21. UserAdmin::ChangeUserName($normalUser,"Tom");//这里传入的是 NormalUser的实例.
  22. echo $normalUser->getName();
  23. ?>

使用接口与组合模拟多继承

通过组合模拟多重继承。

在PHP中不支持多重继承,如果我们向使用多个类的方法而实现代码重用有什么办法么?

那就是组合。在一个类中去将另外一个类设置成属性。

下面的例子,模拟了多重继承。

接口实例

写一个概念性的例子。 我们设计一个在线销售系统,用户部分设计如下: 将用户分为,NormalUser, VipUser, InnerUser 三种。要求根据用户的不同折扣计算用户购买产品的价格。并要求为以后扩展和维护预留空间,代码如下:

  1. <?php
  2. interface User
  3. {
  4. public function getName();
  5. public function setName($_name);
  6. public function getDiscount();
  7. }
  8. abstract class AbstractUser implements User
  9. {
  10. private $name = "";
  11. protected $discount = 0;
  12. protected $grade = "";
  13. function __construct($_name) {
  14. $this->setName($_name);
  15. }
  16. function getName() {
  17. return $this->name;
  18. }
  19. function setName($_name) {
  20. $this->name = $_name;
  21. }
  22. function getDiscount() {
  23. return $this->discount;
  24. }
  25. function getGrade() {
  26. return $this->grade;
  27. }
  28. }
  29. class NormalUser extends AbstractUser
  30. {
  31. protected $discount = 1.0;
  32. protected $grade = "Normal";
  33. }
  34. class VipUser extends AbstractUser
  35. {
  36. protected $discount = 0.8;
  37. protected $grade = "VipUser";
  38. }
  39. class InnerUser extends AbstractUser
  40. {
  41. protected $discount = 0.7;
  42. protected $grade = "InnerUser";
  43. }
  44. interface Product
  45. {
  46. function getProductName();
  47. function getProductPrice();
  48. }
  49. interface Book extends Product
  50. {
  51. function getAuthor();
  52. }
  53. class BookOnline implements Book
  54. {
  55. private $productName;
  56. protected $productPrice;
  57. protected $Author;
  58. function __construct($_bookName) {
  59. $this->productName = $_bookName;
  60. }
  61. function getProductName() {
  62. return $this->productName;
  63. }
  64. function getProductPrice() {
  65. $this->productPrice = 100;
  66. return $this->productPrice;
  67. }
  68. public function getAuthor() {
  69. $this->Author = "chenfei";
  70. return $this->Author;
  71. }
  72. }
  73. class Productsettle
  74. {
  75. public static function finalPrice(User $_user, Product $_product, $number) {
  76. $price = $_user->getDiscount() * $_product->getProductPrice() * $number;
  77. return $price;
  78. }
  79. }
  80. $number = 10;
  81. $book = new BookOnline("设计模式");
  82. $user = new NormalUser("tom");
  83. $price = Productsettle::finalPrice($user, $book, $number);
  84. $str = "您好,尊敬的" . $user->getName() . "<br />";
  85. $str .= "您的级别是" . $user->getGrade() . "<br />";
  86. $str .= "您的折扣是" . $user->getDiscount() . "<br />";
  87. $str .= "您的价格是" . $price;
  88. echo $str;
  89. ?>