很多时候,我们定义了一些对象以后,在使用的时候会发现,某个方法不太适用目前的某个要求了,但是由于这个方法在其他地方多次使用,我们又不能修改这个方法,如果再新建一个class的话,其余的方法又都重复了,这个时候我们就可以使用class间的继承了,继承就像儿子继承父亲的财产一样,子对象可以直接使用父对象的方法,也可以重写父对象的方法,我们先看一个简单的例子:
class man {
public $height=180;
public function getHeight(){
echo "I'm father,my height is :".$this->height;
echo "<br>";
}
public function la(){
echo "啦啦啦<br>";
}
}
class son extends man{
public $height=120;
public function getHeight(){
echo "I'm son,my height is :".$this->height;
echo "<br>";
}
}
$man = new man();
$son = new son();
$man->getHeight();//调用父对象自己本身的方法
$son->getHeight();//调用子对象自己本身的方法
$son->la();//调用父对象方法
我们定义了一个man对象。然后又定义了一个son对象,son 使用extends 关键字 继承了man,表示son是man的子对象。需要注意的是,一个父对象可以有多个子对象,我们可以写很多个对象来继承man。但是子对象只能有一个父对象,这个就不解释了。
下面的执行的代码,前四行我们都不多解释了,最后一行$son->la();我们son对象里并没有定义la()这个方法,但是依然可以输出,这也就是继承特点,子对象可以直接调用父对象的方法。其实子对象也可以直接调用父对象的属性,比如我们删除了son里面height的定义,然后在执行,依然可以输出,只不过输出的身高变成了父对象设置的高度属性。简单点来说,就相当于,如果子对象自己有,就优先用自己的,自己没有就用父对象的,如果父对象也没有,就继续找父对象的父对象,依次类推。如果都找不到则报错。
子对象也可以定义一些和父对象无关的方法去使用。就是子对象和父对象的方法不要求完全一致
当子对象重写父对象方法的时候,参数列表也必须要一致,简单说就是个数要一致,除了构造函数以外,父方法有几个参数,对应的子方法也要有几个参数。
需要特别说明的是,一个类的私有方法或者变量是private类型的时候,子类是不能直接使用的。比如:
class man {
private $height=180;
public function getHeight(){
echo "I'm father,my height is :".$this->height;
echo "<br>";
}
}
class son extends man{
public function getHeight(){
echo "I'm son,my height is :".$this->height;
echo "<br>";
}
}
$son = new son();
$son->getHeight();
我们给man定义了一个私有变量$height,在son里面并没有定义$height,然后我们试图使用$son->getHeight();的时候,就会报错。
class还有一种变量类型。在前面我们并没有介绍,放到这里介绍比较合适,关键字:
protected意思就是受保护的类型,这种类型只能本身和子对象才可以调用,其他地方则不能调用,比如:
class man {
protected $height=180;
public function getHeight(){
echo "I'm father,my height is :".$this->height;
echo "<br>";
}
}
class son extends man{
public function getHeight(){
echo "I'm son,my height is :".$this->height;
echo "<br>";
}
}
$man = new man();
$son = new son();
$man->getHeight();
$son->getHeight();
我们定义了一个protected 类型的变量,然后在子类里面使用,发现可以正常使用,而当我们试图在外部直接赋值的时候$son->height = 120;则会报错提示我们找不到height这个属性。而把height改成public以后,则可以正常赋值。
静态方法和变量的继承,几乎和非静态的差不多,只需要注意一下保持都是静态的就行了,这里就不过多介绍了,喜欢动手的朋友可以自己试一下,也许会发现什么惊喜。下面我们再介绍几个关于class的知识点。
parent:
使用parent关键字,字对象可以访问父对象被字对象覆盖的方法,具体使用形式是parent::functionname();比如
class man {
protected $height=180;
public function getHeight(){
echo "I'm father,my height is :".$this->height;
echo "<br>";
}
}
class son extends man{
protected $height=120;
public function getHeight(){
echo "I'm son,my height is :".$this->height;
echo "<br>";
parent::getHeight();
}
}
$man = new man();
$son = new son();
$man->getHeight();
$son->getHeight();
在子方法里面使用parent::getHeight();调用已经被覆盖的getHeight方法。执行结果如下:
I'm father,my height is :180
I'm son,my height is :120
I'm father,my height is :120
看到这里,就会感觉很奇怪了,为什么最后输出的是120?这里就是class的一些处理机制问题了,我们知道子对象可以覆盖父对象的public和protected类型的属性和方法。在php处理的过程中 ,父对象的属性,是完全被覆盖的,相当于消失了,所以最后才会输出120, 而私有的属性则不会被覆盖,使用parent的时候,则会继续使用父对象的属性,我们再简单的看一个例子:
class man {
public $height=180;
protected $weight = 65;
private $sex = "男";
public function getData(){
echo "I'm father,height:$this->height,weight:$this->weight,sex:$this->sex<br/>";
}
}
class daughter extends man{
public $height=120;
protected $weight = 45;
public $sex = "女";
public function getData(){
echo "I'm daughter,height:$this->height,weight:$this->weight,sex:$this->sex<br/>";
parent::getData();
}
}
$daughter = new daughter();
$daughter->getData();
输出结果为:
I'm daughter,height:120,weight:45,sex:女
I'm father,height:120,weight:45,sex:男
我们很明显的可以看到,身高和体重,父对象里面调用的时候,都被子对象覆盖了,而性别是私有属性,子对象无法覆盖,所以性别输出还是男。class允许继承的时候修改属性的类型,但是只能范围变得更大,而不能变小,比如private可以修改为public,反之则不行。
final:
父对象声明的final类型的方法,不允许子对象覆盖,否则会报错
转载请注明出处:https://blog.csdn.net/shuchuan0409/article/details/80417864