类的继承和三种访问限定控制符
总结:
1.类的继承 关键字 extends
一个类可以在声明中用 extends,关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。 当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。
子类继承父类时,会继承父类的属性和方法,除了 private 的属性和方法外,其它的都可以直接访问和调用,只能通过在父类中定义的访问器来访问。
2.访问限定控制符
public : 类中,类外均可访问, 子类中也可以访问
protected: 类中,类外不可访问, 但是子类中可以访问
private: 只允许在类中, 类外, 子类中不可访问
3.构造方法(魔术方法)__construct
在类实例化的时候会自动触发,一般用来初始化属性值;
实例
<?php namespace _9030; class Demo1 { //属性(变量), public 公共的,公开的,谁都可以用的 public $product = '手机'; public $price = 5800; //private表示私有的,只有本类内部可以使用;例如成本是***内部才知道 private $chengben; //protected表示受保护的,只有本类或子类或父类中可以访问;例如专利是受保护的 protected $zhuanli; // 构造方法 // 前面加了二个下划线的方法, 又叫魔术方法 // 魔术方法不需要用户手工调用,是由php根据某种条件自动触发 public function __construct($chengben, $zhuanli) { // 1. 初始化对象的状态,由属性决定 $this->chengben = $chengben; $this->zhuanli = $zhuanli; // 2. 完成对象创建时的自动化操作 echo $this->getInfo3(); } //方法(函数) public function getInfo1() { // 当前类的引用: self $obj = new self(); echo '商品名称:'.$obj->product.'----'.'商品价格:'.$obj->price.'<br><hr>'; } public function getInfo2() { // 当前类的引用: self // 当前对象的引用: $this, 伪变量 // 1. 类的实例化 // $this = new self(); // 2. 访问类中成员,用对象访问 return '商品名称: ' . $this->product.', 商品价格: ' . $this->price; } public function getInfo3() { return '制造成本: ' . $this->chengben.', 专利归属: ' . $this->zhuanli; } public function getInfo4() { echo '商品名称:'.$this->product.'----'.'商品价格:'.$this->price.'<br><hr>'; } } //访问普通成员属性(public)的三种方式 //1,实例话类,然后用对象直接访问类属性 // $obj = new Demo1(); // echo '商品名称:'.$obj->product.'----'.'商品价格:'.$obj->price.'<br><hr>';//商品名称:手机----商品价格:5800 //2.通过方法来直接获取输出 // $obj->getInfo1();//商品名称: 手机---商品价格: 5800 // 通过方法获取数据后返回输出 // echo $obj->getInfo2();//商品名称: 手机, 商品价格: 5800 //3.由于使用了__construct 构造方法,在实例化该类的时候会自动触发 //并且由于实在类的内部调用的私有的$chengben和受保护的$zhuanli,可以直接输出 new Demo1('2000','诺基亚');//制造成本: 2000, 专利归属: 诺基亚 echo'<hr>'; //4.如果直接在类的外部访问 protected 和 private 会报错 // $obj = new Demo1(); // $this->chengben = '2000'; // $this->zhuanli = '诺基亚'; // echo '制造成本: ' . $this->chengben.', 专利归属: ' . $this->zhuanli; //5.类的继承 关键字 extends // 一个类可以在声明中用 extends,关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。 //被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。 // 当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。 class Sub1 extends Demo1 { } //由于子类Sub1继承了父类Demo1 ,所以通过子类可以访问父类的属性和方法 $obj=new Sub1(2000,'华为');//制造成本: 2000, 专利归属: 华为 echo'<br>'; $obj->getInfo4(); //6.子类的功能扩展 class Sub2 extends Demo1 { //在子类中新添加了一个属性 public $num; public $zhuanli_price; //又创建了一个构造方法 public function __construct($chengben, $zhuanli, $num,$zhuanli_price){ parent::__construct($chengben, $zhuanli); $this->num =$num; $this->zhuanli_price =$zhuanli_price; } //添加了一个计算总和的方法的方法 public function total(){ return round($this->zhuanli_price * $this->num, 3); } } $sub2 = new Sub2(3000,'摩托摩拉',5,888888.88888); echo ',专利总价'.$sub2->total(); //制造成本: 3000, 专利归属: 摩托摩拉,专利总价4444440 echo'<hr>'; //7.方法重置 class Sub3 extends Sub2 { // 重写计算总和,加上折扣率 public function total(){ $total = parent::total(); // 设置折扣率 switch(true){ case($total>4444444&&$total<6666666): $zhekou=0.88; break; case($total>=6666666&&$total<8888888): $zhekou=0.77; break; case($total>=8888888): $zhekou=0.66; break; default: $zhekou=1; } $zhekou_zongjia = round($total * $zhekou,3); if($zhekou<1){ return '折率后总价:'.$zhekou_zongjia.'元<span style="color: red">('.$zhekou.'折)</span>'; }else{ return $zhekou_zongjia; } } } $sub3 = new Sub3(3000,'苹果',7,888888.88888); echo '<br>'.$sub3->total(); echo'<hr>'; // 访问控制符 // public : 类中,类外均可访问, 子类中也可以访问 // protected: 类中,类外不可访问, 但是子类中可以访问 // private: 只允许在类中, 类外, 子类中不可访问 class Demo2 { //类中成员:属性(成员属性).方法(成员方法) //对象属性:需要使用类的实例进行访问的成员属性 public $name;//姓名 protected $postion;//职位 private $salary;//工资 protected $department;//部门 //构造方法,初始化赋值 public function __construct($name,$postion,$salary,$department) { $this->name = $name; $this->postion = $postion; $this->salary = $salary; $this->department = $department; } //职位访问器->方法 public function getPostion(){ return $this->department === '硬件研发部' ? $this->postion : '无权查看' ; } //工资访问器->方法 public function getSalary(){ return $this->department === '硬件研发部' &&$this->name === '大雄' ? $this->salary : '无权查看' ; } } $obj= new Demo2('大雄','软件开发',6666,'硬件研发部'); echo '职位:'.$obj->getPostion().'<br>'; echo '工资:'.$obj->getSalary(); class Sub extends Demo2 { public function display() { // return $this->name; // public在子类中可以访问 // return $this->postion; // protected 在子类中可以访问 // return $this->salary; // private 在子类中无法访问 // return $this->getSalary();// private 在子类中无法访问 可以通过父类中定义的方法,在子类中调用得到返回值 return parent::salary; } } echo '<hr>'; $sub = new Sub('大雄','软件开发',6666,'硬件研发部'); echo $sub->display(), '<br>';
运行实例 »
点击 "运行实例" 按钮查看在线实例