问题

一个静态类或者非静态类,多个方法依赖一个函数,如何实现?

回答
没问题,咱们就聊聊一个类里好多个方法,都离不开一个“基础动作”时,怎么把这个“基础动作”整合起来,让代码更省事儿,也更好看。

想象一下,你写了一个班,里面有好几个方法,比如“做早餐”、“准备午餐”、“做晚餐”。这些方法都有一个共同点:都需要“烧火”。这个“烧火”就是咱们说的那个“基础动作”,或者说是一个核心函数。

情况一:静态类,核心函数也是静态的

如果这个班本身是个“静态班”,也就是说,你不需要先创建一个班的对象,直接用班名就能调用里面的方法。那么,这个“烧火”这个基础动作,自然也得是个静态方法。

怎么做?
很简单,就把那个“烧火”的函数直接定义成 `static` 吧。这样,班里的其他 `static` 方法,在需要烧火的时候,就能直接 `ClassName.烧火()` 这么调用了。

举个例子?
假设你有个 `KitchenHelper` 静态类,里面有个 `fireUpStove()` 静态方法。

```java
public static class KitchenHelper {
// 这是我们的“基础动作”
private static void fireUpStove() {
System.out.println("生火开始,火焰熊熊燃烧...");
}

public static void makeBreakfast() {
fireUpStove(); // 调用“烧火”
System.out.println("煎鸡蛋,烤面包,准备早餐。");
}

public static void makeLunch() {
fireUpStove(); // 再次调用“烧火”
System.out.println("炒菜,蒸米饭,准备午餐。");
}

public static void makeDinner() {
fireUpStove(); // 第n次调用“烧火”
System.out.println("炖肉,煲汤,准备晚餐。");
}
}
```

你看,`makeBreakfast`、`makeLunch`、`makeDinner` 这几个方法,每次都要用 `fireUpStove()`,而 `fireUpStove()` 是 `static` 的,所以直接用类名就能调用。这种方式简洁明了,适合那些不关心“谁”在烧火,只关心“烧火”这个动作本身的方法。

情况二:非静态类,核心函数也是非静态的(最常见的情况)

这可能是最常见也最符合我们日常思考模式的情况。你有一个“厨师”的班,这个厨师有很多技能(方法),比如做饭、备菜。而“烧火”是厨师的一个基本功,每个厨师都会,也都需要在做饭前做这个事。

怎么做?
在这个非静态类里,你就把那个“烧火”的函数定义成一个普通的、非静态的方法。然后,班里其他需要烧火的方法,直接 `this.烧火()` 或者就直接 `烧火()` 就可以了。

举个例子?
假设你有个 `Chef` 类,里面有个 `startFire()` 方法。

```java
public class Chef {
// 这是我们的“基础动作”
private void startFire() {
System.out.println("厨师开始生火,炉灶准备就绪。");
}

public void prepareMeal() {
startFire(); // 调用“烧火”
System.out.println("洗菜、切菜,为烹饪做准备。");
}

public void cookDish() {
startFire(); // 再次调用“烧火”
System.out.println("下锅翻炒,美味佳肴即将出炉。");
}

public void bakeCake() {
startFire(); // 第n次调用“烧火”
System.out.println("预热烤箱,开始烘焙。");
}
}
```

在这种情况下,你得先创建一个 `Chef` 对象,比如 `Chef myChef = new Chef();`,然后再调用 `myChef.prepareMeal()`、`myChef.cookDish()` 等等。每个方法内部都会调用 `startFire()`。

为什么要这么做?
封装性好: “烧火”这个动作是厨师这个“对象”的能力,而不是某个独立的、没有生命的服务。把它放在 `Chef` 类里,意味着“烧火”是厨师的一部分,符合面向对象的设计思想。
可扩展性: 未来如果需要不同类型的厨师,比如“法餐厨师”和“中餐厨师”,它们烧火的方式可能略有不同。你可以让 `Chef` 类有一个默认的 `startFire`,然后让子类去重写(override)这个方法,实现各自独特的烧火方式。

情况三:非静态类,核心函数是私有的(更进一步的封装)

有时候,这个“烧火”的动作,其实是给类内部其他方法用的,外部代码根本不需要知道“烧火”这个具体是怎么进行的,他们只需要知道“做饭”这个事情的发生。

怎么做?
将那个核心函数(比如 `startFire`)的访问修饰符设置为 `private`。这样,只有同在一个 `Chef` 类里的方法才能访问到它。

举个例子?
上面的 `Chef` 类的例子,`startFire` 方法已经是 `private` 了,这正是我们想要的。

```java
public class Chef {
// 私有方法,只允许类内部调用
private void startFire() {
System.out.println("厨师启动炉灶,准备火焰...");
}

// 某个准备动作
public void prepareIngredients() {
// here, we don't necessarily need to start fire
System.out.println("洗、切、配,准备好所有食材。");
}

// 烹饪主菜
public void cookMainCourse() {
startFire(); // 内部调用私有方法
System.out.println("大火快炒,香气四溢。");
}

// 制作甜点
public void makeDessert() {
startFire(); // 内部再次调用私有方法
System.out.println("烘烤甜点,甜蜜的滋味。");
}
}
```

这样做的好处?
隐藏实现细节: 外部调用者不需要关心“烧火”是怎么实现的,他们只需要调用 `cookMainCourse` 或者 `makeDessert`。这让你的代码接口更干净,更专注于“做什么”而不是“怎么做”。
易于维护: 如果未来你想改变“烧火”的具体方式(比如从燃气灶换成电磁炉),你只需要修改 `startFire` 方法的内部逻辑,而不需要改动任何调用它的地方,因为它们都不知道 `startFire` 的内部实现。

什么时候考虑用其他方式?(简单提一下,但不是重点)

虽然上面这两种(静态类+静态方法,非静态类+非静态方法)已经涵盖了绝大多数情况,但如果你觉得“烧火”这个动作非常通用,可以被很多不相关的类使用,而且你不想把所有调用它的类都写成一个大整体,那么可以考虑:

工具类 (Utility Class): 创建一个专门的 `FireStarter` 工具类,里面的 `startFire()` 是静态的。然后,各个类在需要的时候去调用 `FireStarter.startFire()`。
设计模式: 比如策略模式(Strategy Pattern),可以将“烧火”的行为抽象成一个接口,然后不同的实现类(比如 `GasStoveFire`、`ElectricStoveFire`)提供不同的烧火逻辑。主类持有这个策略接口的引用,在需要时调用。

不过,对于你提出的“多个方法依赖一个函数”这个场景,最直接、最符合逻辑的解决方案就是把这个依赖的函数整合到类内部,如果是静态类就用静态函数,如果是非静态类就用普通函数(通常设为私有以隐藏细节)。这种方式使得代码结构清晰,易于理解和维护,并且能很好地体现面向对象的设计思想。

网友意见

user avatar

这个不是OO领域的问题,所以在那本书是找不到所谓的模式的,说的我又想吐槽那本书了,哎,算了。

从这个需求来说,一般来说实现方式是InvokeProxy

即方法调用代理,即不直接调用方法,而使用一个代理去调用,.Net Remoting的透明代理,WCF自动构建的客户端代理乃至MVC的ActionInvoker都是这个思想的实现。

大体上就是这样。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有