簡介
在php中,類型的繼承使用extends關(guān)鍵字,而且最多只能繼承一個(gè)父類,php不支持多繼承。
class MyClass
{
public $dat = 0;
public function __construct($dat) {
$this->dat = $dat;
}
public function getDat() {
return "$this->dat\n";
}
}
class MySubClass extends MyClass
{
public function getDat() {
return "dat: $this->dat\n";
}
}
$a = new MyClass(3);
$b = new MySubClass(4);
echo $a->getDat(); // 3
echo $b->getDat(); // dat: 4
方法覆蓋
包括構(gòu)造函數(shù)在內(nèi),子類可以重新定義同名的類方法以覆蓋父類方法。覆蓋時(shí)遵循以下規(guī)則:
1.除構(gòu)造函數(shù)之外,其他函數(shù)在覆蓋時(shí),函數(shù)的參數(shù)列表必須相同
2.包括構(gòu)造函數(shù)在內(nèi),方法被覆蓋后,調(diào)用子類方法時(shí)并不會(huì)自動(dòng)調(diào)用父類方法
3.如果父類要禁止方法被子類覆蓋,可以使用final來聲明方法,這時(shí)如果子類仍要覆蓋父類方法,將會(huì)出錯(cuò)
class MyClass
{
private $name = "";
public $num = 0;
public $str = "";
public function __construct($name) {
$this->name = $name;
$this->num = 100;
$this->str = "none";
}
public function getName() {
return $this->name;
}
}
class MySubClass extends MyClass
{
public function __construct($name, $str) {
parent::__construct($name); // 調(diào)用父類方法
$this->num = "0";
$this->str = $str;
echo parent::getName()."\n"; // 調(diào)用父類方法
}
public function getName() {
return parent::getName()."$this->str\n"; // 調(diào)用父類方法
}
}
$b = new MySubClass("myName", true); // myName
echo $b->getName(); // myName1
class MyClass
{
final public function getName() {
}
}
屬性重定義
在子類中,可以訪問父類中的public和protected屬性成員,除非重定義了同名的自有屬性,這時(shí),父類中的屬性將無法訪問。
方法則不同,子類對方法進(jìn)行覆蓋后,仍然可以訪問到父類方法。
class MyClass
{
public $a = 1;
protected $b = 2;
private $c = 3;
public function f1() {
echo "MyClass f1\n";
echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";
}
protected function f2() {
echo "MyClass f2\n";
echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";
}
private function f3() {
echo "MyClass f3\n";
}
}
class MySubClass extends MyClass
{
public $b = 22;
public $c = 33;
public function f1() {
echo "MySubClass f1\n";
// 繼承到父類中的$a屬性,直接使用
echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";
// 調(diào)用父類中的同名方法
parent::f1();
// 繼承到父類中的f2()方法,直接使用
$this->f2();
}
// 父類的f3()是私有的,這里的定義與父類無關(guān)
public function f3() {
echo "MySubClass f3\n";
}
}
$b = new MySubClass;
$b->f1();echo "\n";
/*
MySubClass f1
$a:1; $b:22; $c:33;
MyClass f1
$a:1; $b:22; $c:3;
MyClass f2
$a:1; $b:22; $c:3;
*/
$b->f3();echo "\n";
/*
MySubClass f3
*/
重定義父類(同名)屬性時(shí),屬性的可訪問性可以變得更開放,但不能更嚴(yán)格,也就是說,父類中的public屬性,不能在子類中修改為private屬性。
如果通過子類對象調(diào)用父類方法,那么該父類方法在訪問屬性時(shí),對于重定義了的同名屬性,public和protected的屬性將訪問到子類版本,private屬性將訪問到父類版本。也可以理解為,public和protected屬性可以被重定義(父類的版本被重定義,從而不存在了),而private并未被重定義(父類中的屬性仍然存在,通過父類方法進(jìn)行訪問,與子類中是否有同名屬性毫不相干)。
class MyClass
{
public $a = 1;
protected $b = 2;
private $c = 3;
public function f1() {
echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";
}
}
class MySubClass extends MyClass
{
public $a = 11; // 必須為public
protected $b = 22; // 必須為protected或public
private $c = 33;
public function f2() {
echo "\$a:$this->a; \$b:$this->b; \$c:$this->c;\n";
}
}
$b = new MySubClass;
$b->f1(); // $a:11; $b:22; $c:3;
$b->f2(); // $a:11; $b:22; $c:33;
范圍解析操作符 ::
又冒號(hào)常用于訪問類常量、類靜態(tài)變量,也用于在方法覆蓋時(shí)調(diào)用父類版本。與其搭配的還包括parent、self、static等關(guān)鍵字。
class MyClass
{
const Name0 = "MyClass"; // 類常量
public static $id0 = 0; // 類變量
public function put() { // 將被子類覆蓋的方法
echo "MyClass put()\n";
}
}
class MySubClass extends MyClass
{
const Name1 = "MySubClass";
public static $id1 = 1;
public function put() {
parent::put(); // 調(diào)用父類版本的對象方法
echo parent::Name0 . "\n"; // 父類常量
echo parent::$id0 . "\n"; // 父類變量
echo self::Name1."\n"; // 子類常量
echo self::$id1 . "\n"; // 子類變量
echo static::Name1 . "\n"; // 子類常理
echo static::$id1 . "\n"; // 子類變量
}
}
$a = "MyClass";
$ca = new MyClass;
$cb = new MySubClass;
$cb->put();
echo MyClass::Name0 . "\n";
echo MyClass::$id0 . "\n";
echo $a::Name0 . "\n";
echo $a::$id0 . "\n";
echo $ca::Name0 . "\n";
echo $ca::$id0 . "\n";
在子類中訪問父類中的成員時(shí),應(yīng)避免直接使用父類類名,而應(yīng)使用parent::,以免破壞父類的封裝性。
final
聲明為final的方法不能被子類覆蓋,如果類聲明為final,則此類不能被繼承。
// 聲明為final的類不能被繼承
final class MyClass
{
private $dat;
public function __construct($dat) {
$this->dat = $dat;
}
// final方法不能被覆蓋,不過此類已經(jīng)是final類,方法無必要在聲明為final了
final public function getDat() {
return $this->dat;
}
}
總結(jié)
以上所述是小編給大家介紹的php中的類與對象(繼承),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
您可能感興趣的文章:- PHP面向?qū)ο笕筇攸c(diǎn)學(xué)習(xí)(充分理解抽象、封裝、繼承、多態(tài))
- php面向?qū)ο笕ヂ?(七) 繼承性
- PHP入門教程之面向?qū)ο蟮奶匦苑治?繼承,多態(tài),接口,抽象類,抽象方法等)
- PHP面向?qū)ο蟪绦蛟O(shè)計(jì)高級特性詳解(接口,繼承,抽象類,析構(gòu),克隆等)
- PHP面向?qū)ο罄^承用法詳解(優(yōu)化與減少代碼重復(fù))
- PHP面向?qū)ο蟪绦蛟O(shè)計(jì)OOP繼承用法入門示例
- PHP面向?qū)ο蟪绦蛟O(shè)計(jì)繼承用法簡單示例
- PHP面向?qū)ο蟪绦蛟O(shè)計(jì)之接口的繼承定義與用法詳解
- PHP學(xué)習(xí)記錄之面向?qū)ο螅∣bject-oriented programming,OOP)基礎(chǔ)【類、對象、繼承等】
- PHP 對象繼承原理與簡單用法示例