php 自定义类,在PHP中使用自定义类的最佳方法是什么?

我知道你有些人会假设接口或抽象,但这只能处理一些情况.这是他们打破的一个例子.

假设我们有类实现相同的接口并扩展相同的基础

class car extends fourwheeler implements ipaygas{

protected $tank1;

//interface

public function payGas($amount){}

}

class sportscar extends fourwheeler implements ipaygas{

protected $tank1;

protected $tank2;

//interface

public function payGas($amount){}

}

interface ipaygas{

function payGas($amount);

}

在某些情况下,您只需要一个界面,因为您可能只想执行’payGas()’.但是当你有条件要做时,你会怎么做.

例如,如果 – 在支付燃气之前,您需要(1)检查汽车类型,(2)使用跑车的优质汽油,以及(3)填充跑车的第二个油箱.

这是我想要做的但是不能做到的

function pumpAndPay(iPayGas $car){

if(gettype($car) == "car"){

fillTank($car,(car) $car->tank1);

}else{

fillTank($car,(sportscar) $car->tank1);

fillTank($car,(sportscar) $car->tank2);

}

}

我怎么能用真正的类型铸造呢?在PHP中有可能吗?

更新(根据回复):

在我的’真实’案例中……想象一下我必须检查各种车型,每种车型都有不同的油漆,车身,内饰,gas_type,cleaner_type,颜色等……

abstract class AVechicle{}

abstract class ACar extends AVechicle{}

abstract class ATruckOrSUV extends AVechicle{}

abstract class ABike extends AVechicle{}

class Car extends ACar{}

class SportsCar extends ACar{}

class SUV extends ATruckOrSUV{}

class Truck extends ATruckOrSUV{}

class Bike extends ABike{}

class Scooter extends ABike{}

class GasStation{

public function cleanVehicle(AVehicle $car){

//assume we need to check the car type to know

//what type of cleaner to use and how to clean the car

//if the car has leather or bucket seats

//imagine we have to add an extra $2/h for sports cars

//imagine a truck needs special treatment tires

//or needs inspection

}

public function pumpAndPay(AVehicle $car){

//need to know vehicle type to get gas type

//maybe we have a special for scooters only, Green Air campaign etc.

}

public function fullService(AVehicle $car){

//need to know if its a truck to do inspection FIRST

$this->cleanVehicle($car);

$this->pumpAndPay($car);

//bikes get 10% off

//cars get free carwash

}

}

接口和摘要本身只会到目前为止……

解决方法:

简短回答你的问题,不,你不能将对象重铸到另一个对象.

然而,Dan Lee的反应非常好,接近我的建议.为什么不将fillTank作为车辆对象的属性,这样扩展车辆类的所有对象都将知道如何填充自己的坦克.像这样的东西:

abstract class Vehicle

{

protected $tank1;

protected $tank2;

// Declaring an abstract function in parent class forces all child class to

// implement same class

abstract public function fillGas() {}

}

class Car extends Vehicle

{

public function fillGas()

{

$this->tank1 = 'full';

}

}

class SportsCar extends Vehicle

{

public function fillGas()

{

$this->tank1 = 'full';

$this->tank2 = 'full';

}

}

class Skateboard extends Vehicle

{

// Skateboards don't have gastanks, just here to sastify parent abstract definition

public function fillGas() {}

}

当然,你的OP的一个大谬论就是你假设所有的跑车都有两个油箱,而事实并非如此.只有某些跑车有多个油箱.

另一种方法是看一下特征(available as of PHP 5.4).看起来您可以强制实现接口以及跨不扩展同一类的对象的实现.

– 更新 –

Update (Based on responses): In my ‘real’ case… imagine I have to check various Vehicle types, each with different paint, body, interior, gas_type, cleaner_type, color, etc…

你提到的所有这些属性都是车辆属性,而不是gastation,fillstation,parkinglot等属性,因此我会将所有这些属性添加到车辆类中,然后你可以将车辆传递给GasStation :: cleanVehicle()工厂方法来操纵车辆属性.

下面的代码片段仅为DEMONSTRATIVE,演示了如何将上述属性附加到车辆类别,以及GasStation类如何根据车辆类别操纵车辆属性.我在5分钟内编写了以下内容,但显然需要更多考虑正确处理工厂方法以及是否传递给其他对象等.请考虑以下内容:

abstract class Vehicle

{

// Setting these to public for demonstration only, otherwise you should set these

// to protected and write public accessors

public $paintType;

public $bodyType;

public $interior;

}

class Car extends Vehicle

{

}

class Suv extends Vehicle

{

}

class Truck extends Vehicle

{

}

class GasStation

{

public static function cleanVehicle(Vehicle $vehicle)

{

switch (get_class($vehicle)) {

case 'Car':

// Car specific cleaning

break;

case 'Truck':

// Truck specific cleaning

break;

default:

throw new Exception(sprintf('Invalid $vehicle: %s', serialize($vehicle)));

}

// We've gone through our vehicle specific cleaning, now we can do generic

if ('Leather' === $vehicle->getInterior()) {

// Leather specific cleaning

}

if ('Sedan' === $vehicle->getBodyType()) {

// Sedan specific cleaning

}

}

}

$car = new Car();

$car->setPaintType = 'Glossy';

$car->setBodyType = 'Sedan';

$car->setInterior = 'Cloth';

$suv = new Suv();

$suv->setPaintType = 'Glossy';

$suv->setBodyType = 'Crossover';

$suv->setInterior = 'Leather';

$truck = new Truck();

$truck->setPaintType = 'Flat';

$truck->setBodyType = 'ClubCab';

$truck->setInterior = 'Cloth';

$vehicles = array($car, $suv, $truck);

foreach ($vehicles as $vehicle) {

GasStation::cleanVehicle($vehicle);

}

标签:typeof,php,class,casting

来源: https://codeday.me/bug/20190826/1729637.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值