php面向对象学习积累(一)

1.在类的外部(非继承),只能访问共有(public)属性和方法。

class shopProduct{
	protected $title="com";
	public $name="main";
	protected function getProducer(){
		return $this->name;
	}
}

$shopproduct=new shopProduct();
echo $shopproduct->name;//在类的外部只能访问publi属性

2.子类可以访问父类的非私有属性和方法,只有在类中才能访问private方法和属性

class shopProduct{
	protected $title="com";
	public $name="main";
	protected function getProducer(){
		return $this->name;
	}
}

class chProduct extends shopProduct{
	public function gettitle(){
		return $this->title;//子类可以访问父类的非private属性和方法
	}
}

$chproduct=new chProduct();
echo $chproduct->getch();

3.如果派生类没有定义构造方法,那么在实例化的时候会默认调用父类构造方法;如果子类定义了构造函数,需要同时调用父类构造函数,那么应该用parent::__construct() 

class shopProduct{
	public $title;
	public $price;
	function __construct($title,$price){
		$this->title=$title;
		$this->price=$price;
	}
}

class chProduct extends shopProduct{
	public $playlength;
	function __construct($title,$price,$playlength){
		parent::__construct($title,$price);
		$this->playlength=$playlength;
	}
	function getsum(){
		return "title:{$this->title},price:{$this->price},playlength:{$this->playlength}";
	}
}

$chproduct=new chProduct(1,2,3);
echo $chproduct->getsum();

4.parent关键字可以在任何覆写父类方法的方法中使用。覆写一个父类的方法时,

我们并不希望删除父类的功能,而是扩展它。

function getSum(){
$base=parent::getSum();
$base.=":page count - {$this->numPages}";
return base;
}

5.一般来说,我们倾向于严格控制可访问性。最好将类的属性初始化为private或protected,然后在需要的时候再放松限制条件。类中的许多方法都可以是public,然后如果拿不定主意的话,就限制一下。有些类方法只为类中其他方法提供本地功能,与类外部的代码没有任何联系,应该将其设置为private或protected。 

6.静态方法是以类为作用域的函数。静态方法不能访问这个类中的普通属性,因为那些属性属于一个对象,但可以访问静态属性。因为是通过类而不是实例来访问静态元素,所以访问静态元素时不需要引用对象的变量,而是使用::(两个冒号)来连接类名和属性或类名和方法。我们曾使用::和parent来访问覆写的方法。现在和之前一样,只不过访问的是类而不是对象数据。一个子类可以使用parent关键字来访问父类,而不使用其类名。要从当前类(不是子类)中访问静态方法或属性,可以使用self关键字。self指向当前类,就像伪变量$this指向当前对象一样。

class StaticExample{
    static public $aNum=0;
    static public function sayHello(){
        print "hello";
    }
}

print StaticExample::$aNum;
StaticExample::sayHello();

7.getInstance方法根据类型标志聪明的判断需要实例化的对象。这个方法就像“工厂”一样,这个就是工厂模式。

class shopProduct{
    private $id=0;
    public function setID($id){
        $this->id=$id;
    }
    public static function getInstance($type){
        if($type=="book"){
            $product=new BookProduct();
        }else if($type=="cd"){
            $product=new CdProduct();
        }else{
            $product=new ShopProduct();
        }
        return $product;
    }
}

8.常量属性,有些属性不能改变。在类中用const关键字来声明,与静态属性一样,只能通过类而不能通过类的实例访问常量属性。

class ShopProduct{
    const AVAILABLE=0;
    const OUT_OF_STOCK=1;
}

print ShopProduct::AVAILABLE;

9.抽象类不能被直接实例化,抽象类中只定义(或部分实现)子类需要的方法。子类可以继承它并且通过实现其中的抽象方法,使抽象类具体化。大多数情况下,抽象类至少包好一个抽象方法。抽象方法用abstract关键字声明,其中不能有具体内容。

abstract class ShopProductWriter{
    protected $products=array();
    public function addProduct(ShopProduct $shopProduct){
        $this->products[]=$shopProduct;
    }
    abstract public function write();
}

创建抽象方法后,要确保所有子类中都实现了该方法。

10.抽象类提供了具体实现的标准,而接口则是纯粹的模板。接口只能定义功能,而不包含实现的内容。接口可用关键字interface来声明。接口可以包含属性和方法的声明,但是方法体为空。

interface Chareable{
    public function getPrice();
}

class ShopProduct implements Chareable{
    // ...
    public function getPrice(){
        return ($this->price-$this->discount);
    }
    // ...
}

11.错误处理,文件放错地方,数据库服务器未初始化,url有变动,xml文件损坏,这些问题时常发生。要对付这些可能出现的错误,一个简单的类方法有时会充满了错误处理代码。

class Conf{
    private $file;
    private $xml;
    private $lastmatch;
    
    function __construct($file){
        $this->file=$file;
        $this->xml=simplexml_load_file($file);
    }

    function write(){
        file_put_contents($this->file,$this->xml->asXML());
    }
   
}

可以使用throw关键字和Exception对象来抛出异常。这会停止执行当前方法,并负责将错误返回给调用代码。下面修改一下__construct和write方法,使其使用throw语句。

function __construct($file){
    $this->file=$file;
    if(!file_exists($file)){
        throw new Exception("file does not exist");
    }
    $this->xml=simplexml_load_file($file);
}

function write(){
    if(!is_writeable($this->file)){
        throw new Exception("file is not writeable");
    }
    file_put_contents($this->file,$this->xml->asXML());
}

__construct()和write()方法现在可以在工作时不停地检查文件错误,但是代码还应该更好地对检测到的错误作出响应。

try{
    $conf=new Conf(dirname(__FILE__)."/conf01.xml");
    $conf->write();
}catch(Exception $e){
    die($e->_toString());
}

当抛出异常时,调用作用域中的catch子句会被调用,自动将Exception对象作为参数变量传入。

异常的子类化:

class XmlException extends Exception{
    private $error;
    function __construct(LibXmlError $error){
        $shortfile=basename($error->file);
        $msg="[{$shortfile},line {$error->line},col {$error->col}] {$error->message}";
        $this->error=$error;
        parent::__construct($msg,$error->code);
    }
    function getLibXmlError(){
        return $this->error;
    }
}

class FileException extends Exception{}
class ConfException extends Exception{}

//Conf类
function __construct($file){
    $this->file=$file;
    if(!file_exists($file)){
        throw new FileException("file does not exist");
    }
    $this->xml=simplexml_load_file($file,null,LIBXML_NOERROR);
    if(!is_object($this->xml)){
        throw new XmlException(libxml_get_last_error());
    }
    print gettype($this->xml);
    $matches=$this->xml->xpath("/conf");
    if(!conut($matches)){
        throw new ConfException("could not find root element:conf");
    }
}

function write(){
    if(!is_writeable($this->file)){
        throw new FileException("file is not writeable");
    }
    file_put_contents($this->file,$this->xml->asXML());
}

下面是实例化对象Conf的代码

class Runner{
    static function init(){
        try{
            $conf=new Conf(dirname(__FILE__)."/conf01.xml");
            $conf->write();
        }catch(FileExcepiton $e){
            //文件权限问题或文件不存在
        }catch(XmlException $e){
            //XML文件损坏
        }catch(XmlException $e){
            //错误的XML文件格式
        }catch(Exception $e){
            //后备捕捉器,正常情况下不应该被调用
        }
    }
}

11.final关键字可以防止覆写类或方法,final类不能有子类。

final class Checkout{
    // ...
}

12.拦截器,_get() 访问未定义的属性时被调用,_set()给未定义的属性赋值时被调用,_isset()对未定义的属性调用isset()时被调用,_unset()对未定义的属性调用unset()时被调用,_call()调用未定义的方法时被调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值