批改状态:合格
老师批语:总结的非常棒, 全部写在注释中, 也是一个好方法
类的继承和三种访问限定控制符
总结:
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>';点击 "运行实例" 按钮查看在线实例
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号