JAVA 实现潜在类型机制 --《JAVA编程思想》 63

本文探讨了Python和C++中的潜在类型机制,允许对象在不强制公共接口的情况下调用特定方法。在Java中,通过实现接口来达到类似效果,但当方法名不一致时,适配器模式成为解决方案。DuckAdapter示例展示了如何将Duck类的方法映射到Action接口的方法,以优雅地实现潜在类型机制。

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

为了尽可能地广泛应用代码,我们希望通过各类途径来放开类型所作的限制,但同时又不能丢失静态类型的检查。

在 Python 和 C++ 中便有这种解决方案,称为“潜在类型机制”或“结构化类型机制”。我们不关心具体类型,只要求实现某个方法子集(不要求是公共接口),我们便可进行调用。即“如果它走起来像鸭子,并且叫起来也像鸭子,那么你就可以将它当作鸭子对待”。

潜在机制类型可以横跨类继承结构,调用不属于某个公共接口的方法。

我们来看一段 Python 代码,如下所示:

class Dog:
	def speak(self):
		print "Arf!"
	def sit(self)
		print "Sitting!"
class Roboot:
	def speak(self):
		print "Click!"
	def sit(self)
		print "Clank!"
	def oilChange(self):
		pass
def perform(anything):
	anything.speak()
	anything.sit()
a = Dog()
b = Reboot()
perform(a)
perform(b)

anything 可以是任何类型,只要该对象支持 speak() 和 sit() 方法,就能正常执行,否则会得到运行时异常。

但 JAVA 中并不能直接支持潜在类型机制,需要我们实现一个类或者接口,调用公共方法才能达到此类需求。

public interface Action {

    void speak();

    void sit();

}
public class Dog implements Action{

    @Override
    public void speak() {
        System.out.println("Arf!");
    }

    @Override
    public void sit() {
        System.out.println("Sitting!");
    }

}
public class Reboot implements Action{

    @Override
    public void speak(){
        System.out.println("Click!");
    }

    @Override
    public void sit(){
        System.out.println("Clank!");
    }

    public void oilChange(){
        return;
    }

}


public class ActionTest {

    public static void action(Action action) {
        action.speak();
        action.sit();
    }

    public static void main(String[] args) {
        action(new Dog());
        action(new Reboot());
    }

}
Arf!
Sitting!
Click!
Clank!

Dog 和 Reboot 分别实现 Action 接口,再通过泛化的 Action 调用需要共用的 speak() 和 sit() 方法。

但这里需要注意的是,假设我们需要抽取的公共方法不同名该怎么办?如下面这个 Duck 类。

public class Duck {

    public void cry(){
        System.out.println("DA!");
    }

    public void down(){
        System.out.println("PU!");
    }
    
}

我们需要将 cry() 对应 speak() ,down() 对应 sit() ,该怎么办呢?

其实也不复杂,使用适配器模式,便可解决问题。

public class DuckAdapter extends Duck implements Action {

    @Override
    public void speak() {
        super.cry();
    }

    @Override
    public void sit() {
        super.down();
    }

}
public class ActionTest {

    public static void action(Action action) {
        action.speak();
        action.sit();
    }

    public static void main(String[] args) {
        action(new Dog());
        action(new Reboot());
        action(new DuckAdapter());
    }

}
Arf!
Sitting!
Click!
Clank!
DA!
PU!

DuckAdapter 继承 Duck ,实现 Action 接口,在实现接口的方法中再调用父类中需要作为共用的方法,从而更为优雅的实现潜在类型机制。

本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。

若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaymaxCS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值