ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# abstract 抽象类 ## **abstract 抽象类** > 抽象类就是定义规则的保持子类行为统一 抽象类特点: - 1.抽象类是指在class前加了abstract关键字且存在抽象方法(在类方法function关键字前加了abstract关键字)的类。 - 2.抽象类不能被直接实例化。抽象类中只定义(或部分实现)子类需要的方法。子类可以通过继承抽象类并通过实现抽象类中的所有抽象方法,使抽象类具体化。 - 3.如果子类需要实例化,前提是它实现了抽象类中的所有抽象方法。如果子类没有全部实现抽象类中的所有抽象方法,那么该子类还是一个抽象类,必须在class前面加上abstract关键字,并且不能被实例化。**子类继承**抽象类,就必须**定义(相当于重写)实现**抽象类中的方法;即抽象父类中带有abstract的方法必须被子类继承,否则子类还是抽象类,也不能实例化 - 4:可以定义属性、方法、抽象方法 - 5:抽象方法没有方法体(即无花括号)abstract public function eat(); - 6:抽象类不能实例化只能被子类继承调用 定义了抽象类,就是让你子类继承,实现具体的抽象方法 - 7:抽象类中可以没有抽象方法,但是有抽象方法的类必须定义为抽象类 例子1: ``` <pre class="calibre10">``` abstract class <span class="token4">AbstractClass</span> <span class="token3">{</span> <span class="token">// 强制要求子类定义这些方法 </span> abstract protected <span class="token5">function</span> <span class="token4">getValue</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> abstract protected <span class="token5">function</span> <span class="token4">prefixValue</span><span class="token3">(</span>$prefix<span class="token3">)</span><span class="token3">;</span> <span class="token">// 普通方法(非抽象方法) </span> public <span class="token5">function</span> <span class="token4">printOut</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> print $this\<span class="token1">-</span><span class="token1">></span><span class="token4">getValue</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">.</span> <span class="token2">"\\n"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> class <span class="token4">ConcreteClass1</span> extends <span class="token4">AbstractClass</span> <span class="token3">{</span> protected <span class="token5">function</span> <span class="token4">getValue</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token2">"ConcreteClass1"</span><span class="token3">;</span> <span class="token3">}</span> public <span class="token5">function</span> <span class="token4">prefixValue</span><span class="token3">(</span>$prefix<span class="token3">)</span> <span class="token3">{</span> <span class="token5">return</span> <span class="token2">"{$prefix}ConcreteClass1"</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $class1 <span class="token1">=</span> <span class="token5">new</span> <span class="token4">ConcreteClass1</span><span class="token3">;</span> ``` ``` **列子:2** ``` <pre class="calibre10">``` abstract class <span class="token4">Person</span> <span class="token3">{</span> <span class="token">// 属性 </span> public $name <span class="token1">=</span> <span class="token2">'芙蓉姐姐'</span><span class="token3">;</span> protected $sex <span class="token1">=</span> <span class="token2">'Unknown'</span><span class="token3">;</span> private $age <span class="token1">=</span> <span class="token6">18</span><span class="token3">;</span> public <span class="token5">function</span> <span class="token4">say</span><span class="token3">(</span><span class="token3">)</span> <span class="token3">{</span> echo <span class="token2">'上课了,就不要睡觉觉了'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token">// 抽象方法 </span> abstract public <span class="token5">function</span> <span class="token4">eat</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//1抽象方法无花括号;2抽象类可以没有抽象方法只要Person类前加了abstract不要这行代码也是抽象类 </span> <span class="token3">}</span> <span class="token">// 实例化Person类 </span> $p <span class="token1">=</span> <span class="token5">new</span> <span class="token4">Person</span><span class="token3">;</span> <span class="token">// Cannot instantiate(实例化) abstract class Person 不能被实例化</span> class <span class="token4">girl</span> extends <span class="token4">Person</span><span class="token3">{</span> public <span class="token5">function</span> <span class="token4">eat</span><span class="token3">(</span><span class="token3">)</span><span class="token3">{</span> echo<span class="token2">'吃东西吃出大姨妈了'</span><span class="token3">;</span> <span class="token3">}</span> <span class="token3">}</span> $pp<span class="token1">=</span><span class="token5">new</span> <span class="token4">girl</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token4">var_dump</span><span class="token3">(</span>$pp<span class="token3">)</span><span class="token3">;</span><span class="token">//object(girl)#1 (3) { ["name"]=> string(12) "芙蓉姐姐" ["sex":protected]=> string(7) "Unknown" ["age":"Person":private]=> int(18) } </span> $pp<span class="token1">-</span><span class="token1">></span><span class="token4">say</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span>上课了,就不要睡觉觉了' $pp<span class="token1">-</span><span class="token1">></span><span class="token4">eat</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span><span class="token">//吃东西吃出大姨妈了</span> ``` ``` php7.2起,当一个抽象类继承于另外一个抽象类的时候,继承后的抽象类可以重写被继承的抽象类的抽象方法 ``` <pre class="calibre17">``` abstract class <span class="token4">A</span> <span class="token3">{</span> abstract <span class="token5">function</span> <span class="token4">test</span><span class="token3">(</span>string $s<span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> abstract class <span class="token4">B</span> extends <span class="token4">A</span> <span class="token3">{</span> <span class="token">// 覆盖 - still maintaining contravariance for parameters and covariance for return</span> abstract <span class="token5">function</span> <span class="token4">test</span><span class="token3">(</span>$s<span class="token3">)</span> <span class="token3">:</span> int<span class="token3">;</span> <span class="token3">}</span> ``` ```