设计一个PHP程序,实现以下要求: 创建一个父类 Vehicle,包含以下内容: 公有属性 $brand(品牌)、受保护属性 $maxSpeed(最大速度); 构造函数初始化 $brand 和 $maxSpeed; 公有方法 getInfo(),返回字符串:"品牌:{品牌},最大速度:{最大速度} km/h"; 受保护方法 checkSpeed($speed),若输入速度大于 $maxSpeed,返回 false,否则返回 true。 创建子类 Car,继承 Vehicle,并扩展以下功能: 新增私有属性 $color(颜色); 重写构造函数,额外初始化 $color; 新增公有方法 setColor($color) 和 getColor(); 重写 getInfo(),追加颜色信息,格式:"品牌:{品牌},最大速度:{最大速度} km/h,颜色:{颜色}"; 新增公有方法 safeDrive($speed),调用父类 checkSpeed() 判断速度是否安全,返回对应的提示信息。
时间: 2025-06-25 13:19:40 浏览: 15
<think>嗯,我现在需要设计一个PHP程序,按照用户的要求创建一个父类Vehicle和一个子类Car。让我仔细看看用户的需求,然后一步步思考怎么实现。
首先,父类Vehicle需要有公有属性$brand,受保护的属性$maxSpeed。构造函数用来初始化这两个属性。然后有一个公有的方法getInfo(),返回包含品牌和最大速度的字符串。还有一个受保护的方法checkSpeed,检查输入速度是否超过maxSpeed,超过返回false,否则true。
子类Car要继承Vehicle,新增私有属性$color。需要重写构造函数,不仅要初始化父类的属性,还要初始化color。还要有setColor和getColor方法。重写getInfo(),在父类的基础上加上颜色信息。然后新增一个safeDrive方法,调用父类的checkSpeed来判断速度是否安全,返回相应的提示。
好的,首先处理父类Vehicle。在PHP中,类用class关键字定义。公有属性是public,受保护的是protected。构造函数用__construct,参数应该包括brand和maxSpeed。然后方法getInfo返回格式化字符串,这里需要用双引号或者用连接符,比如"品牌:{$this->brand},最大速度:{$this->maxSpeed} km/h"。不过要注意,maxSpeed是受保护的,所以在父类内部可以通过$this->maxSpeed访问,子类也可以。
checkSpeed方法是受保护的,接受一个$speed参数,判断是否超过maxSpeed。如果$speed大于$this->maxSpeed返回false,否则true。
然后是子类Car,继承使用extends Vehicle。私有属性$color。子类的构造函数需要调用父类的构造函数,可以用parent::__construct()来初始化brand和maxSpeed,然后再设置color。PHP中,子类构造函数如果重写的话,必须显式调用父类的构造函数吗?如果不调用的话,父类的构造函数不会自动执行。所以Car的构造函数应该有三个参数:brand, maxSpeed, color,然后调用parent::__construct($brand, $maxSpeed),再设置$this->color = $color。
setColor方法用来设置color的值,而getColor返回当前颜色。这两个方法是公有的。
重写getInfo方法,需要在父类的基础上添加颜色。可以先调用父类的getInfo,然后追加颜色信息吗?或者直接重写整个字符串。例如,在Car的getInfo中,可以获取父类的getInfo返回的字符串,然后拼接颜色部分。或者直接重新构造字符串。比如:
public function getInfo() {
return "品牌:{$this->brand},最大速度:{$this->maxSpeed} km/h,颜色:{$this->color}";
}
不过,如果父类的getInfo的格式改变的话,子类需要同步修改,可能不太好。所以另一种方法是先获取父类的信息,然后添加颜色。比如:
public function getInfo() {
$parentInfo = parent::getInfo();
// 父类的返回是"品牌:xx,最大速度:yy km/h",所以需要把最后的"替换掉,加上颜色部分
// 但可能需要用字符串处理,或者直接重构。可能直接重构更简单,因为父类的结构已知。
return parent::getInfo() . ",颜色:{$this->color}";
}
这样会更灵活,如果父类修改了getInfo的格式,子类自动继承,并添加颜色部分。例如,假设父类的getInfo返回的是"品牌:A,最大速度:100 km/h",那么子类就会返回"品牌:A,最大速度:100 km/h,颜色:红色"。这个方法可能更好,因为避免了重复代码。
不过,这里父类的getInfo返回的是品牌和maxSpeed,而maxSpeed在父类中是受保护的属性,子类可以访问吗?是的,因为protected属性在子类中可以访问。所以在Car类中,$this->maxSpeed是可以访问的。所以可以直接拼接字符串,或者调用父类的getInfo然后追加。
可能两种方法都可以。但用户要求子类重写getInfo,所以可能需要完全覆盖父类的实现。或者可能用父类的实现,然后加上颜色。这需要看用户的需求。用户说“重写getInfo(),追加颜色信息”,所以应该是基于父类的getInfo结果,再添加颜色。因此,在子类的getInfo中,先调用父类的getInfo,然后加上颜色部分。
那怎么处理呢?比如:
public function getInfo() {
$originalInfo = parent::getInfo();
// 假设父类返回的是"品牌:XX,最大速度:YY km/h"
// 要改成"品牌:XX,最大速度:YY km/h,颜色:ZZ"
return $originalInfo . ",颜色:{$this->color}";
}
这样的话,如果父类的getInfo格式改变,子类会自动适应。例如,如果父类后来在getInfo中添加其他信息,子类也会在最后追加颜色。
这可能更符合用户的需求。那么,在子类Car中,getInfo方法应该是这样实现的。
然后是safeDrive方法,这个方法是公有的,接受$speed参数,然后调用父类的checkSpeed方法。但checkSpeed是受保护的,所以在子类中可以访问。所以,safeDrive方法可以这样写:
public function safeDrive($speed) {
if ($this->checkSpeed($speed)) {
return "安全,当前速度{$speed} km/h未超过最大速度{$this->maxSpeed} km/h";
} else {
return "危险!当前速度{$speed} km/h已超过最大速度{$this->maxSpeed} km/h";
}
}
因为checkSpeed是受保护的,子类可以通过$this->checkSpeed()调用。
但是,父类的checkSpeed是protected,所以子类可以直接使用。是的。所以在safeDrive里调用$this->checkSpeed($speed)是正确的。
现在,把这些代码结构写出来。
父类Vehicle:
class Vehicle {
public $brand;
protected $maxSpeed;
public function __construct($brand, $maxSpeed) {
$this->brand = $brand;
$this->maxSpeed = $maxSpeed;
}
public function getInfo() {
return "品牌:{$this->brand},最大速度:{$this->maxSpeed} km/h";
}
protected function checkSpeed($speed) {
return $speed <= $this->maxSpeed;
}
}
子类Car:
class Car extends Vehicle {
private $color;
public function __construct($brand, $maxSpeed, $color) {
parent::__construct($brand, $maxSpeed);
$this->color = $color;
}
public function setColor($color) {
$this->color = $color;
}
public function getColor() {
return $this->color;
}
public function getInfo() {
return parent::getInfo() . ",颜色:{$this->color}";
}
public function safeDrive($speed) {
if ($this->checkSpeed($speed)) {
return "安全,当前速度{$speed} km/h未超过最大速度{$this->maxSpeed} km/h";
} else {
return "危险!当前速度{$speed} km/h已超过最大速度{$this->maxSpeed} km/h";
}
}
}
这里需要注意的地方:
1. 子类Car的构造函数是否正确调用父类的构造函数?是的,通过parent::__construct传递brand和maxSpeed。
2. checkSpeed在子类中是否能被调用?是的,因为它是protected,子类内部可以访问。
3. safeDrive方法是否正确使用checkSpeed的结果,并返回相应的字符串?是的,当checkSpeed返回true时表示安全,否则危险。
测试一下这个代码:
比如创建Car实例:
$car = new Car("Toyota", 200, "红色");
echo $car->getInfo(); // 应该输出品牌:Toyota,最大速度:200 km/h,颜色:红色
echo $car->safeDrive(180); // 安全,当前速度180未超过200
echo $car->safeDrive(220); // 危险!220超过200
另外,setColor和getColor是否正确?
$car->setColor("蓝色");
echo $car->getColor(); // 应该返回蓝色,然后getInfo也会更新。
父类的属性brand是public,所以外部可以直接访问,比如$car->brand。而maxSpeed是protected,所以外部不可访问。color是private,只能在Car内部访问,所以外部必须通过getColor方法获取。
这样设计应该满足用户的要求。可能需要注意的点是构造函数是否正确初始化所有属性,方法的访问权限是否正确,以及是否正确地覆盖了父类的方法。</think>根据需求,我们将分步实现PHP程序。以下是完整的代码实现及说明:
```php
<?php
// 父类 Vehicle
class Vehicle {
// 公有属性
public $brand;
// 受保护属性
protected $maxSpeed;
// 构造函数初始化属性
public function __construct($brand, $maxSpeed) {
$this->brand = $brand;
$this->maxSpeed = $maxSpeed;
}
// 公有方法返回基本信息
public function getInfo() {
return "品牌:{$this->brand},最大速度:{$this->maxSpeed} km/h";
}
// 受保护方法校验速度
protected function checkSpeed($speed) {
return $speed <= $this->maxSpeed;
}
}
// 子类 Car
class Car extends Vehicle {
// 新增私有属性
private $color;
// 重写构造函数(需调用父类构造函数)
public function __construct($brand, $maxSpeed, $color) {
parent::__construct($brand, $maxSpeed);
$this->color = $color;
}
// 新增颜色设置方法
public function setColor($color) {
$this->color = $color;
}
// 新增颜色获取方法
public function getColor() {
return $this->color;
}
// 重写信息展示(追加颜色)
public function getInfo() {
$baseInfo = parent::getInfo();
return "{$baseInfo},颜色:{$this->color}";
}
// 新增安全驾驶校验
public function safeDrive($speed) {
$isSafe = $this->checkSpeed($speed);
$max = $this->maxSpeed;
return $isSafe
? "安全,当前速度{$speed} km/h未超过最大速度{$max} km/h"
: "危险!当前速度{$speed} km/h已超过最大速度{$max} km/h";
}
}
// 测试代码
$car = new Car('Toyota', 200, '红色');
echo $car->getInfo() . PHP_EOL; // 品牌:Toyota,最大速度:200 km/h,颜色:红色
echo $car->safeDrive(180) . PHP_EOL; // 安全提示
echo $car->safeDrive(220) . PHP_EOL; // 危险提示
?>
```
### 代码解析:
1. **父类 Vehicle**
- 通过 `public $brand` 和 `protected $maxSpeed` 定义可见性不同的属性
- 构造函数用 `__construct()` 实现属性初始化
- `getInfo()` 返回基础信息字符串
- `checkSpeed()` 受保护方法实现速度校验
2. **子类 Car**
- 通过 `extends Vehicle` 继承父类
- 使用 `parent::__construct()` 调用父类构造函数
- 通过 `parent::getInfo()` 复用父类方法并追加颜色信息
- `safeDrive()` 调用父类受保护方法 `checkSpeed()` 实现业务逻辑
### 关键特性:
- **封装性**:`maxSpeed` 用 `protected` 保护数据,`color` 用 `private` 严格封装
- **继承复用**:子类复用父类构造函数和方法,减少重复代码
- **多态性**:通过方法重写(`getInfo()`)实现差异化输出
- **安全性校验**:`safeDrive()` 方法通过调用父类保护方法实现业务逻辑隔离
### 测试结果:
```bash
品牌:Toyota,最大速度:200 km/h,颜色:红色
安全,当前速度180 km/h未超过最大速度200 km/h
危险!当前速度220 km/h已超过最大速度200 km/h
```
阅读全文
相关推荐


















