如何实现可识别Tile/Primitive/Cube类型并调用set方法的统一方法?
如何实现统一调用不同类的同名方法?
问题描述
我现在有三个逻辑几乎完全相同的方法,唯一区别就是第一个参数的类型分别是Tile、Primitive、Cube,而这三个类都拥有完全相同签名的set(int a, int b, int c)方法:
// 三个类的set方法实现 Tile.set(int a, int b, int c){ ... } Primitive.set(int a, int b, int c){ ... } Cube.set(int a, int b, int c){ ... }
对应的调用方法如下:
void first(Tile tile, int a, int b, int c){ tile.set(a,b,c); } void second(Primitive tile, int a, int b, int c){ tile.set(a,b,c); } void third(Cube tile, int a, int b, int c){ tile.set(a,b,c); }
我想实现一个统一的方法,能自动识别输入的tile参数类型(不管是Tile、Primitive还是Cube),然后调用对应的set方法。比如我尝试过以下错误写法:
// 错误写法1:没有统一的父类型/接口支撑 void monster(Anything tile, int a, int b, int c){ tile.set(a,b,c); } // 错误写法2:参数名重复,语法不合法 void monster(Tile tile, Primitive tile, Cube tile, int a, int b, int c){ tile.set(a,b,c); }
请问有没有正确的实现方式?
解决方案
当然可以实现!这种重复代码的场景,正是面向对象中抽象设计的典型用武之地,下面给你两种可行的方案,根据你的实际情况选择:
方案1:定义公共接口(最优解,若能修改三个类)
这是最符合面向对象设计原则的做法,通过抽象出公共行为,让三个类实现同一个接口:
- 创建公共接口,声明所有类都具备的
set方法:
interface Settable { void set(int a, int b, int c); }
- 让三个类实现该接口:
class Tile implements Settable { @Override public void set(int a, int b, int c) { // 原有实现逻辑 } } class Primitive implements Settable { @Override public void set(int a, int b, int c) { // 原有实现逻辑 } } class Cube implements Settable { @Override public void set(int a, int b, int c) { // 原有实现逻辑 } }
- 编写统一方法,用接口作为参数类型:
void unifiedSet(Settable obj, int a, int b, int c) { obj.set(a, b, c); }
现在你只需要调用unifiedSet方法,不管传入Tile、Primitive还是Cube对象,都会自动调用对应的set方法,完全不需要手动判断类型!
方案2:适配器模式(若无法修改三个类)
如果这三个类是第三方库提供的,你没办法修改它们的代码,那么可以用适配器模式来包装它们,间接实现统一调用:
- 创建适配器接口(和方案1的接口一致):
interface Settable { void set(int a, int b, int c); }
- 为每个类创建适配器:
class TileAdapter implements Settable { private Tile tile; public TileAdapter(Tile tile) { this.tile = tile; } @Override public void set(int a, int b, int c) { tile.set(a, b, c); } } // PrimitiveAdapter和CubeAdapter同理,分别包装Primitive和Cube对象
- 统一调用方法:
void unifiedSet(Settable obj, int a, int b, int c) { obj.set(a, b, c); }
使用的时候,只需要把原始对象包装成适配器传入即可:
Tile myTile = new Tile(); unifiedSet(new TileAdapter(myTile), 1, 2, 3);
内容的提问来源于stack exchange,提问作者Hydraxia
相关产品推荐
相关产品推荐

