php類abstract和final,類方法abstract和final, interface

class修飾符php

final:c++

當final做用於某個類時,此類被限定爲不可繼承類,即其餘類沒法繼承此類,最終類,當你不想讓別人繼承本身的編寫的類時只須要在前面加上final關鍵字便可ide

final class MyClass {
    //code
}

//fatal error final class MyClass can not be inherited by other class
class SubClass extends Myclass {
}

當final做用於某個類方法時,此方法被限定爲不可重寫,即子類中不能夠重寫此方法,並不是不可繼承,類方法能否被繼承依舊被public protected private限定,便父類的fianl private方法沒法被子類繼承,子類中仍然不能重寫此方法函數

php的繼承機制是先檢查此方法是否是final,若爲final子類中仍重寫此方法,則報錯this

只有在不是final時纔會進一步依據public protected private來限定子類是否能繼承此方法spa

且重寫追尋訪問權限必須寬鬆於父類的原則 code

class MyClass {
    final public function finalPublic() {
        echo __METHOD__;
    }
    
    final private function finalPrivate() {
        echo __METHOD__;
    }
    
    final protected function finalProtected () {
        echo __METHOD__;
    }
}
//可調用父類可繼承的方法MyClass::finalPublic() MyClass::finalProtected() 但 MyClass::finalPrivate()將不被繼承
class CorrectSubClass extends Myclass {
}
//由於重寫了父類的final修飾的方法 因此會報錯
class ErrorSubClass extends Myclass {
    public function finalPublic() {
        echo __METHOD__;
    }
    //雖然並不能從父類MyClass中繼承finalPrivate()方法但依舊會由於其被final修飾而報錯
    //弱父類private方法不爲fianl類型,則子類能夠重寫一個private方法
    //private function finalPrivate() {
    //   echo __METHOD__;
    //}
    
    protected function finalProtected () {
        echo __METHOD__;
    }
}


abstract:對象

當abstract做用於某個類時,此類被限定爲抽象類,只能用於繼承,而沒法實例化對象。繼承

抽象類不必定含有抽象方法,但抽象方法必定存在於抽象類中,且繼承此抽象類的子類必須所有實現其抽象方法,不然,子類也要標識爲抽象類。接口

抽象方法是必須被子類繼承實現的,因此不能夠用private修飾符去限定abstract抽象方法,能夠用public和protected去修飾。

abstract class MyClass {
    //抽象方法的定義相似於C/C++中的函數聲明 沒有函數體 其後繼承此類的子類中必須實現此方法 不然子類也必須爲抽象類
    abstract public function abstractFunc();
    abstract public function abstractFuncOther();
    
    public function index() {
    
    }
}

abstract class SubAbstract extends MyClass {
    //不實現父抽象類的抽象方法則自身必須爲抽象類
}

//不然要實現所有抽象方法
class Sub extends MyClass {
    //繼承抽象類若自身不爲抽象類必須實現其父類的全部抽象方法
    public function abstractFunc() {
        
    }
    
    public function abstractFuncOther() {
        
    }
}

實例彙總

<?php
//========================================================================================================================================
//============================================       final類       and      final方法       ==============================================
/**
* final class 不能夠被其餘類繼承 終結類
*/
final class FinalClass
{
	public function index()
	{
		echo "i am " . __METHOD__;
	}
}

/**
 * 含有final method的class 繼承類中不能重寫此類中的final method 
 * final的優先級要高於private 即雖然此類中此方法爲final private method 子類沒法繼承此private方法
 * 但此時依然會由於父類中此私有的方法爲final 不能在子類中自行定義 不給你 也不讓你作一個
 */
class FinalMethod
{
	final public function finalPublic()
	{
		echo __METHOD__ . ' can be inherited, but be overrided' . '<br/>';
	}

	final protected function fianlProtected()
	{
		echo __METHOD__ . ' can be inherited, but be overrided' . '<br/>';
	}

	final private function finalPrivate()
	{
		echo __METHOD__ . ' can not be inherited or be overrided' . '<br/>';
	}
}

class MethodClass extends FinalMethod 
{
	public function index()
	{
		$this->finalPublic();
		$this->fianlProtected();
	}
	//被final限定不可重寫父類全部的fianl方法 不管是否可從父類繼承
	// public function finalPrivate() {

	// }
}
echo '==================== final ======================' . '<br/>';
$method = new MethodClass();
$method->index();

//========================================================================================================================================
//============================================       抽象類       and      抽象方法       ================================================

/**
 * 抽象類 只能用於繼承 不可實例化對象 且抽象類抽象方法可爲零
 * 抽象方法必須存在於抽象類中 抽象方法沒有函數體 相似於c/c++中的函數聲明
 * 繼承此抽象類的子類要麼將此類中的全部抽象方法實現 不然子類也必須爲抽象類
 * 抽象方法不能夠用private去修飾 由於其自己的出發點就是要去被重寫實現的 這點與final剛好相反 final不容許被重寫 abstract必須被重寫 因此在抽象類中private沒有任何意義
 * 抽象方法的訪問級別只能是public或者protected 且子類去實現方法時只能是下降方法的訪問級別而不能提高 即protected能夠被重寫爲public 但public不能重寫爲protected
 * 訪問級別的升降要以頂級抽象方法的聲明爲準則 即便此方法後期被實現後又被繼承 繼承時重寫次方法仍然不能提升訪問級別 只能是下降 始終下降
 */
abstract class AbstractClass
{
	//index()被調用之日此抽象類的所有抽象方法確定已被實現 index()只能經過對象去調用 而實例化對象時則此類的全部抽象方法最終也已被實現
	public function index()
	{
		$this->abstractPublicFunc();
		$this->abstractProtectedFunc();
	}
	// 不能夠用private去修飾 abstract原本就是用於子類繼承實現的 且子類實現此抽象方法時訪問級別必需要小於等於此抽象類定義的
	abstract public function abstractPublicFunc();
	abstract protected function abstractProtectedFunc();
}
/**
 * 只實現了父抽象類中的一個抽象方法 則自身也只能做爲抽象類使用
 */
abstract class SubAbstractClass extends AbstractClass
{
	//抽象方法被具體實現 但後續子類中此方法的訪問級別仍然不能提高 即不能重寫爲protected
	public function abstractPublicFunc()
	{
		echo __CLASS__ . __METHOD__ . '<br/>';
	}
}
/**
 * 父類中的抽象方法都已經被實現 可實例化對象
 */
class ObjectClass extends SubAbstractClass
{
	public function abstractPublicFunc()
	{
		echo __METHOD__ . '<br/>';
	}
	//這裏能夠將此方法的訪問級別設定爲public 但絕對不可能爲private
	public function abstractProtectedFunc()
	{
		echo __METHOD__ . '<br/>';
	}

}
echo '====================abstract=====================' . '<br/>';
$abstract = new ObjectClass();
$abstract->index();

//========================================================================================================================================
//========================================================       接口 interface       ====================================================
/**
 * 接口是用來定義一套行爲標準 任何使用此接口的類都必須追尋接口所聲明的方法標準 是一套不須要使用abstract修飾的但所有爲抽象方法的標準類
 */
interface MyInterface
{
	public function getName();
	public function getAge();
	public function getSex();
}

class User implements MyInterface
{
	private $name = null;
	private $age = null;
	private $sex = null;

	public function __construct($name, $age, $sex)
	{
		$this->name = $name;
		$this->age = $age;
		$this->sex = $sex;
	}

	public function getName()
	{
		echo $this->name . '<br/>';
	}

	public function getAge()
	{
		echo $this->age . '<br/>';
	}

	public function getSex()
	{
		echo $this->sex . '<br/>';
	}
}

$user = new User('sallency', 25, 'male');
echo '====================interface=====================' . '<br/>';
$user->getName();
$user->getAge();
$user->getSex();
?>
相關文章
相關標籤/搜索