php面向对象(oop)特性之继承
继承
继承的现实意义:后代拥有父代的财产和能力
程序的继承:面向对象才有的概念,如果某个类与另外一个类基本上功能差不多,然后稍微会多出一点功能。将这个多出功能的类定义为一个子类,然后基本功能的类定义为父类,然后将子类继承父类。
子类的对象能够拥有子类和父类的所有属性(public和protected)以及方法的使用。
继承的关键字:extends
继承语法
class 父类
{
    
}
//继承
class 子类 extends 父类
{
}
属性继承:所有的非静态属性都被继承
方法继承:
1.公有的(public)可以被继承
2.受保护的(protected)可以被继承
3.私有的(private)不能被继承
继承demo如下:
<?php
   //继承
   //父类
   class Father
    {
        //属性
        public $name = '犬夜叉';   //名字
        protected $money = 1000; //财产
        private    $wife = '桔梗';   //老婆
        //方法
        public function cook()
        {
            echo 'Father cook';
        }
        protected function gongfu()
        {
            echo '家族功夫';
        }
        private function steel()
        {
            echo '偷东西';
        }
        protected function getWife()
        {
            echo $this->wife;
            //$this->steel();
            $this->test();
            //var_dump($this);
        }
    }
   //子类继承父类
   class Son extends Father
    {
        //什么都不做
        public function callFather()
        {
            //$this->gongfu();          //可以继承父类受保护的方法
            //$this->steel();           //不能继承父类私有的方法
            $this->getWife();
        }
        public function callFatherProperty()
        {
            echo $this->name;  //可以
            echo $this->money; //可以
            echo $this->wife;  //不可以
        }
        protected function test()
        {
            echo 'test';
        }
    }
   $son = new Son(); //实例化子类
   //var_dump($son);
   //方法继承
   //$son->cook();        //调用成功,继承了父类中的公有方法
   //$son->gongfu();  //调用失败,继承成功,受保护的方法不能在类外部访问(gongfu在son类中没有所以是调用的父类的gongfu函数 但是gongfu是protected修饰,protected修饰的只能在类中访问,类的外部访问不了 所以这里是成功继承了 但是调用失败。)
   //$son->steel();   //调用失败,继承失败,父类中私有的方法不能被继承
   $son->callFather();
   //$son->callFatherProperty();继承链
1. 凡是使用了extends继承,继承是双向的。只要在继承链上,就可以对链上的其他类的公有和受保护的方法进行访问。
2. 在php中不支持多重继承(一个子类继承自多个父类),使用链式结构实现多重继承
B extends A
C extends B C既有B类的属性和方法,又有A类的属性和方法。
3. 私有的属性或者方法都必须在对应的类中才能被访问,其他地方都不可以。
4. 如果子类拥有与父类同名的属性或者方法会怎么样?这就是接下来我们要说的重写的概念啦
重写(override)
当子类拥有与父类同名的方法或者属性的时候,会重写父类的属性和方法。(前提是:非私有的才可以被重写
1.如果在子类重写了父类的方法之后,需要父类的同名方法也执行。
2.parent关键字: 代表父类,其实parent代表的父类对象
3.重写要求: 子类的权限要比父类的权限(权限就是访问修饰符[public,protected,private])要开放(或者子类的权限大于等于父类的权限)
重写demo如下:
//重写
class  Father
{
    //属性
    public $name = '康熙';
    protected $money  = 20000;
    private $age = 69;
    //方法
    public function publicFather()
    {
        echo __METHOD__,'<br/>';
    }
    protected function protectedFather()
    {
        echo __METHOD__,'<br/>';
    }
    private function privateFather()
    {
        echo __METHOD__,'<br/>';
    }
    public function call()
    {
        $this->publicFather();
        $this->protectedFather();
        $this->privateFather();
    }
}
//子类
class Son extends Father
{
    //属性
    public $name = '雍正';
    protected $money = 40000;
    private $age = 42;
    //方法
    public function publicFather()
    {
        //Father::publicFather();
        //parent::publicFather();    //调用父类的publicFather()方法  输出:Father::publicFather
        echo __METHOD__,'<br/>';  //输出:Son::publicFather
    }
    protected function protectedFather()
    {
        echo __METHOD__,'<br/>';
    }
    private function privateFather()
    {
        echo __METHOD__,'<br/>';
    }
}
//实例化
$son = new Son();
//var_dump($son);
//调用方法
//$son->call();
//调用子类覆盖父类的方法
$son->publicFather();   //输出:Son::publicFather特殊类
final类
final: 最终的意思
类: final修饰的类,表示该类不能被继承。
方法: final修饰的方法,不允许子类重写
final demo如下:
//final类的测试
final class Son
{
    public function __construct()
    {
        echo __METHOD__;
    }
}
/*
class Grade extends Son
{
}
$grade = new Grade(); //报错: 使用final修饰的类 不能被继承*/
//final方法的测试
class test1
{
    final public function method1()
    {
        echo 'hell world';
    }
}
class test2 extends test1
{
    public function method1()
    {
        echo 'test1 hello world';
    }
}
$test2 = new test2();
$test2->method1();    //报错  父类中使用final修饰的方法(method1)不能被子类重写abstract类
抽象类: 只能被继承的类,不能被实例化
抽象方法: 方法只有名字没有方法体,方法体就是大括号{} 比如:abstract public function eat(); eat();就是抽象方法
继承抽象类的子类必须实现全部的抽象方法。
抽象类demo如下:
abstract class Person
{
    //属性
    public $name;
    public $age;
    public function setAge($name)
    {
        $this->name = $name;
    }
}
//实例化类
$person1 = new Person(); //报错,abstract修饰的类不能被实例化,只能被继承抽象方法demo:
//抽象类
abstract class Person
{
    //抽象方法
    abstract public function eat();
    //私有方法
    private function test(){}
}
//子类
class Baby extends Person
{
    //实现父类的抽象方法,增加一个方法体,就是增加一个大括号{}
    public function eat()
    {
    }
}
//实例化
$baby = new Baby();抽象类的意义
1. 只能被继承
2. 子类必须实现父类的抽象方法
3. 在于规范团队协作能力(如果有不同的团队去实现不同的方案,有必要对不同的团队进行一些规范,相同功能该如何命名)
抽象类中可以有普通类中所有的内容。(包括各式访问修饰限定符)
接口
专门用于规范整个项目的设计结构的工具称之为接口
接口语法
语法关键字: interface
interface 接口名字{}
接口注意事项如下:
1. 接口不能有非静态属性
2. 接口不能有静态属性
3. 接口里的方法不能有方法体[所谓的方法体就是大括号一对儿{}](必须是抽象方法)
4. 接口里的方法必须使用public修饰
5. 接口内容: 常量+公有的抽象方法
接口demo如下:
//接口
//定义一个接口
interface myInterface
{
    //接口内容
    //属性
    //public $name;          //错误,接口不能有属性
    //public static $age;  //错误,静态属性也不能有
    //常量
    const PI = 3.14;      //可以有常量
    //方法
    //public function test(){echo 'hello world';};   //接口里面只能有抽象方法(不需要使用关键字abstract)
    public function test();
    //私有方法
    //private function test1();       //接口里面不能有私有方法
    //受保护的
    //protected function test2();  //接口里面不能有受保护的(protected)方法
    public static function test3();
}接口的意义
接口是比抽象类还抽象的"类"(与类结构相似)。
接口纯粹用来规范整个项目的结构的。
实现接口
语法: 类 implements(实现) 接口
实现接口demo如下:
//定义一个接口
interface myInterface
{
    public function test();
    
    public static function test3();
}
//实现接口
class Person implements myInterface
{
    //实现接口中所有的抽象方法
    //实现接口的方法的时候,不能对应的权限降低
    public function test()
    {
        echo 'hello world';
    }
    public static function test3()
    {
        echo 'static funciton';
    }
}多接口实现(一个类实现多个接口称为多接口实现)
一个类可以实现多个接口,称之为多接口实现
实现多接口demo如下:
//实现多接口
interface A
{
    public function testA();
}
interface B
{
    public function testB();
}
//定义一个C类,实现A接口和B接口
class C implements A,B
{
    //必须实现接口里的所有方法
    public function testA()
    {
        echo '实现了接口A里的testA方法';
    }
    public function testB()
    {
        echo '实现了接口B里的testB方法';
    }
}接口继承接口(接口与接口之间可以使用extends关键字来联合。)
接口继承接口并实现接口demo如下:
//接口继承接口
interface A
{
    public function test();
    public function testA();
}
//接口继承接口
interface B extends A
{
    public function testB();
}
//实现接口
class C implements B
{
    public function test()
    {
    }
    public function testA()
    {
    }
    public function testB()
    {
        
    }
}一般情况下,小公司不会用这个。大公司或者有多个团队合作的时候需要使用接口来进行项目规范。
问题
1.PHP是否支持多继承?如果不支持,能不能模拟?
答:PHP不支持多继承,可以通过链式继承来模拟一个子类继承多个父类。
2.接口是不是类?
答:接口不是类,类是用关键字class修饰,接口是使用interface(内容结构有点相似)
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。
 
						

 
					 
					 
					
精彩评论