java 接口转化为对象_Java最佳实践:转换对象与接口

假设我们有以下玩具界面:

interface Speakable

{

public abstract void Speak();

}

interface Flyer

{

public abstract void Fly();

}

我们有一个实现两个接口的类:

class Duck implements Speakable, Flyer

{

public void Speak()

{

System.out.println("quack quack don't eat me I taste bad.");

}

public void Fly()

{

System.out.println("I am flying");

}

}

在这一点上,我看到了在Duck上调用方法的不同方法,我无法确定哪一个是最佳实践.

考虑这种情况:

public class Lab

{

private static void DangerousSpeakAndFly(Object x)

{

Speakable temp = (Speakable) x;

temp.Speak();

Flyer temp2= (Flyer) x;

temp2.Fly();

}

public static void main(String[] args)

{

Duck daffy= new Duck();

DangerousSpeakAndFly(daffy);

}

}

这个程序将按预期运行,因为传入函数的对象恰好可以转换为Flyer和Speakable,但是当我看到这样的代码时,我感到畏缩,因为它不允许编译时类型检查,并且由于它可以抛出紧密耦合意外异常,例如当一个不同类型的对象(不能转换为任何一个或一个接口)作为参数传入,或者Duck的实现向下更改,因此它不再实现Flyer.

我看到Java代码一直都是这样编写的,有时候是在教科书中(例如O’Reilly的“Head First Design Patterns”第300页)所以我必须要有一个我缺少的优点.

如果我要编写类似的代码,我会尽量避免向下转换为无法保证的类型或接口.例如,在这种情况下,我会做这样的事情:

interface SpeakingFlyer extends Flyer, Speakable

{

}

class BuzzLightyear implements SpeakingFlyer

{

public void Speak()

{

System.out.println("My name is Buzz");

}

public void Fly()

{

System.out.println("To infinity and beyond!");

}

}

这将允许我这样做:

private static void SafeSpeakAndFly(SpeakingFlyer x)

{

x.Speak();

x.Fly();

}

public static void main(String[] args)

{

BuzzLightyear bly= new BuzzLightyear();

SafeSpeakAndFly(bly);

}

这是不必要的矫枉过正吗?这样做有什么陷阱?

我觉得这个设计将SafeSpeakAndFly()函数与其参数分离,并且由于编译时类型检查而阻止了令人讨厌的错误.

为什么第一种方法在实践中如此广泛地使用而后者不是?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值