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(内容结构有点相似)
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。
精彩评论