处理概括关系之四 :Push Down Method(函数下移)

本文探讨了在面向对象编程中,如何识别并移除超类中的函数,将其推送到与之相关的子类,以提高代码的模块化和可维护性。通过实例说明了这一过程的动机、具体做法以及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

superclass 中的某个函数只与部分(而非全部)subclasses 有关。

将这个函数移到相关的那些subclasses 去。

动机(Motivation)

Push Down Method 恰恰相反于 Pull Up Method 。当我有必要把某些行为从superclass 移至特定的subclass 时,我就使用Push Down Method,它通常也只在这种时候有用。使用Extract Subclass 之后你可能会需要它。

作法(Mechanics)

·在所有subclass 中声明该函数,将superclass 中的函数本体拷贝到每一个subclass 函数中。
Ø你可能需要将superclass 的某些值域声明为protected,让subclass 函数也能够访问它们。如果日后你也想把这些值域下移到subclasses , 通常就可以那么做;否则应该使用superclass 提供的访问函数(accessors)。如果访问函数并非public ,你得将它声明为protected 。

·删除superclass 中的函数。

Ø你可能必须修改调用端的某些变量声明或参数声明,以便能够使用subclass 。

Ø如果有必要通过一个superclass 对象访问该函数,或如果你不想把该函数从任何subclass 中移除,或如果superclass 是抽象类,那么你就可以在superclass 中把该函数声明为抽象函数。

·编译,测试。

·将该函数从所有不需要它的那些subclasses 中删掉。

·编译,测试。

范例:(Example)

我以Customer「表示「顾客」,它有两个subclass  :表示「普通顾客」的RegularCustomer 和表示「贵宾」PreferredCustomer。

两个subclass 都有一个createBill() 函数,并且代码完全一样:

void createBill (date Date) {

   double chargeAmount = charge (lastBillDate, date);

   addBill (date, charge);

}

但我不能直接把这个函数上移到superclass,因为各个subclass 的chargeFor() 函数并不相同。我必须先在superclass 中声明chargeFor()  抽象函数:

class Customer...

   abstract double chargeFor(date start, date end)

然后,我就可以将createBill()  函数从其中一个subclass 拷贝到superclass。拷贝完之后应该编译,然后移除那个subclass 的createBill() 函数,然后编译并测试。 随后再移除另一个subclass 的createBill() 函数,再次编译并测试:

<!-- 帧结构定义表--> <el-table :data="HeadItemData" style="width: 100%" max-height="400" :span-method="handleSpanMethod" >> <el-table-column label="字节序号" width="100"> <template #default="{ row }"> <!-- 新增按钮行渲染 --> <div v-if="row.isActionRow" class="action-row"> <el-button type="primary" style="width: 400px" @click="addItem" >+</el-button > </div> <span v-else :style="{ color: row.byteNo > 32 ? 'red' : 'inherit' }" > {{ row.byteNo }} </span> </template> </el-table-column> <el-table-column label="操作" width="150" fixed="right"> <template v-slot="scope" ><el-button type="text" size="small" class="button-text" @click="moveUp(scope.$index)" :disabled=" scope.$index === 0 || scope.$index === 1 || scope.$index === HeadItemData.length - 2 " >上移</el-button ><el-button type="text" size="small" class="button-text" @click="moveDown(scope.$index)" :disabled=" scope.$index === 0 || scope.$index === HeadItemData.length - 2 || scope.$index === HeadItemData.length - 3 " >下移</el-button ><el-button type="text" size="small" class="button-text" style="color: red" @click="deleteItem(scope.$index)" :disabled=" scope.$index === 0 || scope.$index === HeadItemData.length - 2 " >删除</el-button ></template > </el-table-column> </el-table> const HeadItemData = ref([ { byteNo: 1, len: 1, name: '包头1', dataType: '2', range: '0-255', itemApp: '1', verifyType: '', default: '21930', //55AA startRange: '', endRange: '' }, { byteNo: 2, len: 1, name: '包头2', dataType: '2', range: '0-255', itemApp: '1', verifyType: '', default: '21930', startRange: '', endRange: '' }, { byteNo: 3, len: 1, name: '目标地址', dataType: '2', range: '0-255', itemApp: '3', verifyType: '', default: '21930', startRange: '', endRange: '' }, { byteNo: 4, len: 1, name: '源地址1', dataType: '2', range: '0-255', itemApp: '2', verifyType: '', default: '21930', startRange: '', endRange: '' }])实现addItem
03-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值