php5面向对象入门(二)

本文详细介绍了PHP中类的继承与重写的基本概念,包括构造函数的重写、私有成员的不可继承性、重写方法的权限限制及通过parent::调用父类方法等关键知识点。
 原文作者 刀客羽朋 ,这里重新整理,出处:http://www.cnblogs.com/tograce/category/161526.html

类的继承
类的继承是这样定义的:
<?php
class animal{
......
  }
}
class dog extends animal{
......
}
?>


一个关于继承的简单实例:
 1<?php
 2//animal.php
 3class animal{
 4  private $weight;
 5  public function getWeight()
 6  {
 7    return $this->weight;
 8  }
 9  public function setWeight($w)
10  {
11     $this->weight=$w;
12  }
13}
14?>
15<?php
16//dog.php
17require_once('animal.php');
18class dog extends animal
19{
20    /**子类新增方法*/
21    public function  bark()
22    {
23        echo "Wang~~Wang~~~ ";
24    }
25}
26?>
27
28<?php
29//myDog.php
30require_once('dog.php');
31$myDog=new dog();
32$myDog->setWeight(20);
33echo "Mydog's weight is ".$myDog->getWeight().'<br />';
34$myDog->bark();
35?>
36
说明:

1、在php5中,构造函数可被继承;
2、在php5中,私有变量和私有方法不能被继承。

重写(override)

      如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称方法的重写。
      当对父类的方法进行重写时,子类中的方法必须和父类中的对应的方法具有相同的方法名称,在php5中不限制输入参数类型、参数数量和返回值类型。
      子类中的覆盖方法不能使用比父类中被覆盖方法更严格的访问权限。(这是什么意思?就是说如果父类中的一个方法为public属性的,那每其子类的该方法就不能定义为private属性的)

例子:

重写简单实例
 1<?php
 2// 狗有两只眼睛,会汪汪叫,会跑.
 3class dog{
 4  protected $eyeNumber=2;  //属性
 5  //返回封装属性的方法.
 6  public function getEyeNumber(){
 7    return $this->eyeNumber;
 8  }
 9  //狗会叫
10  public function yaff(){
11     return "Dog yaff, wang..wang..";
12   }
13   //狗会跑
14  public function run(){
15    return "Dog run..running";
16  }
17}  
18$dog=new dog();
19echo "dog have ". $dog->getEyeNumber()." eyes. <br>";
20echo $dog->yaff(). "<br >".$dog->run();
21echo "<br /> <br /> <br /> <br />";
22
23//这是我家的小狗叫"狗狗",它很小,不会汪汪叫,只会哼哼哼
24class smallDog extends dog{
25  private $name="狗狗";
26  public function getName(){
27    return $this->name;
28  }
29  //重写方法yaff()
30  public function yaff(){     
31    return $this->name.",henghegn..";
32  }
33}
34$myDog=new smallDog();
35echo $myDog->getName()."have ".$myDog->getEyeNumber()." eyes. <br>";
36echo $myDog->yaff() ."<br>".$myDog->run();
37?>


构造函数的重写
当子类重写了构造函数,当在子类被实例化时,只调用子类的构造函数,而父类的构造函数不被调用。

Code
 1<?php
 2//构造函数继承的问题.
 3class Animal{
 4    public $legNum = 0;
 5    public function __construct(){
 6        $this->legNum = 4;
 7        echo "I am an animal<br>";
 8    }
 9}
10class Dog1 extends Animal {
11    public function __construct(){
12        $this->legNum = 4;
13        echo "I am a Dog .<br>";
14    }
15}
16$dog1 = new Dog1();
17echo  "legNum is ".$dog1->legNum;
18/*
19输出结果是:
20I am a Dog .
21legNum is 4
22
23实例化子类时.子类的构造函数被调用了.而不调用父类的构造函数
24*/
25?>


this关键字
$this代表其所在的当前对象
$this在构造函数中指该构造函数所创建的新对象
在类中使用当前对象的属性和方法,必须使用$this->取值

来看一个局部变量和属性同名的小例:

Code
 1<!-- 验证属性和局部变量使用方法的类 -->
 2<?
 3class A{
 4    private $a = 99;
 5    //这里写一个打印参数的方法.
 6    public function printInt($a){
 7        echo "这里的 "$a 是传递的参数 $a ";
 8        echo "<br>";
 9        echo "这里的 "$this->a 是属性 $this->a";
10    }
11}
12$a = new A(); // 这里的$a 可不是类中的任何一个变量了.
13$a->printInt(88);
14?>

用$this调用对象中的其它方法

Code
 1<?php
 2//写一个类,让他自动完成最大值的选取
 3class Math{
 4  //两个数比较大小
 5  public function max($a,$b){
 6    return $a>$b?$a:$b;
 7  }
 8  //三个数比较大小
 9  public function max3($a,$b,$c){
10    $a=$this->max($a,$b);
11    return $this->max($a,$c);
12  }
13  /*-----------也可直接这样----
14   public function max3($a,$b,$c){
15    return $this->max($this->max($a,$b),$c);
16  }*/
17}
18$math=new Math();
19echo "max is ".$math->max3(80,140,100);
20?>


用$this调用构造函数
调用构造函数和析构函数是一样的

<?
class A{
    private $a = 0;
    public function __construct(){
        $this->a = $this->a + 1 ;
    }  
    public function doSomeThing(){
        $this->__construct();
        return $this->a;
    }
}
$a = new A(); // 这里的$a 可不是类中的任何一个变量了.
echo "现在 "$a 的值是" . $a->doSomeThing();
?>

输出结果是:现在 "$a 的值是 2

$this到到底是什么?
$this就是指当前对象,我们甚至可以返回这个对象使用$this,

ContractedBlock.gifExpandedBlockStart.gif$this返回当前对象
 1<?php
 2class A{
 3  function getASelf(){
 4    return $this;
 5  }
 6  public function __toString(){
 7    return "这是A的实例";
 8  }
 9}
10$a=new A();//创建A的实例
11$b=$a->getASelf();//调用方法返回当前实例
12echo $a;//打印对象会调用它的_toString方法
13
14?>


 用$this传递对象

ContractedBlock.gifExpandedBlockStart.gifCode
 12-4-8.php <br>
 2<!--通过$this传递对象
 3在这个例子中,我们写一个根据不同的年龄发不同的工资的类
 4我们设置处理年龄和工资的业务模型为一个独立的类.
 5-->
 6<?php
 7class User{
 8  private $age;
 9  private $sal;
10  private $payoff;//声明全局属性
11  
12  //构造函数,并创建Payoff的对象.
13  public function __construct(){
14    $this->payoff = new Payoff();   
15    //★★★
16    /*【评】:通过构造函数,自动声明属性payoff是类Payoff的一实例*/
17  }
18  public function getAge(){
19    return $this->age;
20  }
21  public function setAge($age){
22    $this->age =$age;
23  }
24  //获得工资.
25  public function getSal(){
26    $this->sal = $this->payoff->figure($this);
27     //★★★★★★★
28     /*---------------------------------------------------------------
29     时间:2009-06-30
30     【评】:这是该类的精髓所在:
31     方法getSal()的作用是:①返回属性sal的值;
32                           ②将属性payoff中的方法figure的结果传给属性sal;
33                           ③同时方法figure的参数是$this,为一对象,且是类User本身          
34     --------------------------------------------------------------*/
35    return $this->sal;
36  }
37}    
38
39//这是对应工资和年龄关系的类  
40class Payoff{    
41  public function figure($a){  //★★★这里的参数将是一个对象
42    $sal =0;
43    $age =$a->getAge();
44    /*★★★
45    这一句,我反复看了多遍才明白,当时我的困惑是:
46    $a为一对象,但并没有说是它是类User的一实例,又怎么可以调用方法getAge()呢?
47    看看2009-06-30我的理解正确不正确*/
48    if($age>80 || $age<16){
49      $sal =0;
50    }elseif($age>50){
51      $sal=1000;
52    }else{
53      $sal=800;
54    }
55    return $sal;
56  }
57
58//实例化User
59$user =new User();
60
61$user->setAge(55);
62echo $user->getAge(). "age, his sal is ".$user->getSal();    
63echo "<br />";
64
65$user->setAge(25);
66echo $user->getAge(). "age, his sal is ".$user->getSal();    
67echo "<br />";
68
69$user->setAge(10);
70echo $user->getAge(). "age, his sal is ".$user->getSal();    
71echo "<br />";
72    
73    
74?>
75


输出结果:
55age, his sal is 1000
25age, his sal is 800
10age, his sal is 0


parent::关键字
通过parent::调用父类的方法


ContractedBlock.gifExpandedBlockStart.gifCode
 1<?php
 2//用parent::调用父类的方法
 3//声明一个员工类,经理类继承自员工类
 4class employer{
 5  protected $sal=3000;
 6  public function getSal(){
 7    $this->sal=$this->sal+1200;
 8    return $this->sal;
 9  }
10}
11class manager extends employer{
12  //如果想让经理在员工的基础上多发1500元,
13  //先要调用父类的方法
14  public function getSal(){
15    parent::getSal();  //这里调用了父类的方法
16    $this->sal=$this->sal+1500;
17    return $this->sal;
18  }
19}
20$emp=new employer();
21$manag=new manager();
22echo "普通员工的工资是: ".$emp->getSal()."<br />";
23echo  "经理的工资是: ".$manag->getSal(). "<br />";
24?>
25


将输出:
普通员工的工资是: 4200
经理的工资是: 5700

 

重载Overload
当类中的方法名相同时,称为方法的重载(Overload);
PHP5中不支持重载(Overload)

 

实例

在前面,我们建立一个user类,并可使用类获取用户信息,现在,我们将进一步加强其功能,用户可修改自己的密码。
先需要将前面的类稍修改,在UserInfo类中将获取密码的方法隐藏。
然后再写一个 UserChange 类,它继承自 UserInfo 类,但在这个类中增加修改密码的方法,并将获取密码的方法重写为public权限。

在这里,我们还将连接单独写成一个类 MysqlConn

ContractedBlock.gifExpandedBlockStart.gifCode
<?php
  
class MysqlConn{
  
protected $conn;
  
protected $my_db;
  
protected $result;

  
public function __construct(){
    
require_once("db_config.php");
    
$this->conn=mysql_connect($db_server,$db_user,$db_pwd);//建立连接,
    mysql_query("set names 'utf8'");
    
$this->my_db=mysql_select_db($db_name,$this->conn); 
  }
  
  
public function query($sql){
    
$this->result=mysql_query($sql,$this->conn);
    
return $this->result;
  }
  
  
public function next(){
    
return $row=mysql_fetch_array($this->result);
  }

  
public function close(){
    
mysql_free_result($this->result);  
  }
  
    
//使用转义字符,保证系统安全.
  public  function escapeString($str){
    
return mysql_escape_string($str); 
  }
/*--------------------------------------------
mysql_escape_string与addslashes的区别在于  
  mysql_escape_string总是将“'”转换成“\'”  
   
  而addslashes  
  在magic_quotes_sybase=on时将“'”转换成“''”  
  在magic_quotes_sybase=off时将“'”转换成“\'”
------------------------------------------------
*/    
    
}

?>


加强了的 UserInfo 类

ContractedBlock.gifExpandedBlockStart.gifCode
<?php
//class_user.php
require_once("class_mysqlConn.php");
class UserInfo{
  
protected $userName;
  
protected $birthplace;
  
protected $password;
  
protected $userEmail;
  
protected $theUserInfo;
  
protected $mysqlConn;
  
/*★与前面的class_user_before.php相比,将属性类型更改为protected,并加入了新的属性mysqlConn*/
  
 
public function __construct($name){
  
$this->mysqlConn=new MysqlConn();
  
$sql="select * from user where username='$name'";//查询的sql
  $rs=$this->mysqlConn->query($sql);
  
$this->theUserInfo=$this->mysqlConn->next();
  
$this->getInfo();
  }
  
  
//获取信息传递给属性的方法
  protected function getInfo(){
    
$this->userName=$this->theUserInfo["username"];
    
$this->birthplace=$this->theUserInfo["birthplace"];
    
$this->password=$this->theUserInfo["passwd"];
    
$this->userEmail=$this->theUserInfo["email"];    
  }
  
  
//返回每个属性的public方法.
  public function getUserName(){
    
return $this->userName;
  }
  
  
public function getBirthplace(){
    
return $this->birthplace;  
  }
  
  
protected function getPassword(){
    
return $this->password;  
  }
  
  
public function getEmail(){
    
return $this->userEmail;  
  }
    


子类UserChange 类

ContractedBlock.gifExpandedBlockStart.gifCode
<?
// class_userChange.php
require_once("class_user.php");
class UserChange extends userInfo{
  
public function setUserPSW($pws){
  
    
$pws=$this->mysqlConn->escapeString($pws);//过滤
    $username=$this->mysqlConn->escapeString($this->userName);//过滤
    /*userName属性是protected性质的,但为什么能直接获取属性值呢?
    ----------------------------------------------------------------
*/
    
$sql="Update user set passwd ='$pws'where username ='username'";
    
$rs=$this->mysqlConn->query($sql);//执行
    if ($rs){
      
$this->password=$pws;  
    }
    
return $rs;  //退回它的意义是什么?
  }
  
  
public function getPassword(){//重写getUserPSW方法
        return $this->password; 
  }
  
}
?>


还记得上回用 UserInfo类获取值的实例吗,这里照样可以放心使用:

<?php
//view_user_mysql_process.php
require_once("class_user.php");

$user=new UserInfo("shuwill");

$userName=$user->getUserName();
$birthplace=$user->getBirthplace();
$email=$user->getEmail();

echo "Your name is ".$userName."<br />";
echo "Your birthplace is ".$birthplace."<br />";
echo "Your email is ".$email."<br />";
?>



转载于:https://www.cnblogs.com/tograce/archive/2009/01/06/1370258.html

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值