2014-09-19 15 views
1

我有3个班。如何在Java中隐藏父接口的方法?

public interface Operation { 
    void move(); 
    void delete(); 
    void search(String criteria); 
} 

public abstract class AbstractOperationProcessor implements Operation { 
    public void move() { 
     // some logic 
    } 
} 

public class DailyMailProcessor extends AbstractOperationProcessor{ 
    // need to hide this method because I don't want to provide them to customer 
    public void delete() {} 
    public void search(String criteria) {} 
} 

我需要的是隐藏的方法从API delete()search(String)。如何在不改变接口01​​和抽象类AbstractOperationProcessor的情况下做到这一点?

+0

我认为你只是不能 – Leo 2014-09-19 21:55:59

+0

你可以重新抽象这些方法。这隐藏了实现,但显然这些方法是在'interface'中定义的,所以你无法控制它。 – 2014-09-19 22:02:03

回答

1

正如其他答案已经指出:你不能隐藏超类的方法。还有一个很好的理由,你不能这样做:多态性允许你传递需要超类型对象的子类型的任何对象。在你的情况,如果你有一个方法

void foo(Operation op){op.delete()} 

你可以叫

foo(new DailyMailProcessor()) 

正如你所看到的,富不知道OP的确切类型,但由于删除在操作界面中,方法delete可以被调用。

如果您碰巧想从子类型的界面中删除一些方法,您可能未执行行为子类型!我建议你看看Liskov Principle,这是面向对象编程的基本原理之一。

如果您拥有的不是行为子类型,那么您错误地试图通过继承实现代码重用。你应该使用组合。 。在继承(赞成组成Item 16, Effective Java)有利于你的情况成分的原因是显而易见的:你不必抛出UnsupportedOperationException(如在其他的答案中提到),并在此获得静态安全

编辑:澄清当我告诉你使用组合时,我的意思是:不要让类DailyMailProcessor扩展Operation,而是给它一个类型为Operation的成员变量,并将调用转发给您想要支持成员变量的方法。

public interface Operation { 
    void move(); 
    void delete(); 
    void search(String criteria); 
} 

public class DailyMailProcessor { 
    private Operation op; 
    public DailyMailProcessor {/*instantiate op*/} 
    void move() {op.move();} 
} 
+0

哪个'Design Pattern'是它?这是一个“策略”吗? – Alex 2014-09-19 23:15:04

+0

我会说这只是普通的对象组成。但是看看战略模式的UML图,我认为你可以将任何具有界面的组合看作战略模式的一个例子。在这个例子中,你可以使用不同的“操作”策略。 – 2014-09-19 23:55:15

9

你不行。你可以做的最好的是实现存根抛出类似NotImplementedException并记录下这个事实。

我会用这个机会来检查顶层接口的定义。如果你需要隐藏它的一些方法,那么真正的问题可能是它汇集了无关的功能。您可能需要将其分成两个单独的界面。请记住,您可以“继承”(即实现)多个接口。

+1

即使如此:如果你不打算实现接口,为什么要实现接口? – 2014-09-19 22:03:16

2

你不能那样做。在接口中声明的每个方法都应该由类实现。你可以做的只是实现这些方法,但不给它任何定义。

1

编辑:
正如评论所说,UnsupportedOperationException可能是一个更好的选择。

原来的答复:
还有就是IllegalStateException只是这一点。只是让所有你不想实现的方法抛出。只要做:

public class DailyMailProcessor extends AbstractOperationProcessor { 

    public void delete() { 
     throw new IllegalStateException(); 
    } 

    public void search(String criteria) { 
     // do something useful here 
    } 
} 
+3

'IllegalStateException' doc。说:“表示一种方法在非法或不适当的时间被调用。” - 我宁愿在这种情况下抛出'UnsupportedOperationException'。 – qqilihq 2014-09-19 22:02:06

+0

但这不是非法的状态。 'UnsupportedOperationException'也许,但是实现一个接口只是为了不实现接口。 – 2014-09-19 22:02:39

+1

@ T.J.Crowder当然有一些用例 - “List ”接口的操作被标记为“可选操作”,一些实现类没有实现。但我认为接口的文档标记它们很重要,并且可能提供一个布尔方法来测试它是否被实现,这样编写使用它的类的人就会意识到这种可能性。 – ajb 2014-09-19 22:07:15

0

是处理你的probleme,当且仅当你想拥有它的埃莱方式,是使用组件系统和它看起来有些这样那样的最佳解决方案:

abstract class Component { 
abstract void perform(); 
} 

abstract class Move extends Component { 
void perform() { ... } 
} 

class AbstractOperationProcessor { 
List<Component> components; 
... 
}