我如何构建一个实现接口中受保护方法的系统?

时间:2014-03-21 13:41:24

标签: java oop logic

我正在建立一个小的lwjgl库。

我有一个RenderController,包含所有渲染对象和其他可渲染的对象 - 所以我采用了一个名为Renderable的接口 - 包含方法render()和。 beforeRenderUpdate()。 问题是:不应该允许库的用户调用RenderObject#update,因为我希望lib单独管理渲染。但我希望用户允许拥有此类的实例,因为它们有时会扩展AbstractMovableObject,并且用户必须移动它们或请求统一更新。 因此,创建包含render方法的抽象类的选项是不可能的。 interfacr的优势在于,我在RenderController中有一个列表,对象<Renderable>(x).render()

但我不想公开这个渲染方法。我现在能做什么?令我难过的是,抽象类是不可能的,因为这些类正在扩展其他东西。

3 个答案:

答案 0 :(得分:1)

您可以利用SOLID principles Interface Segregation Principle中的I

使用2个接口,一个用于公共内容,一个用于私有内容。仅将对象公开给用户作为公共接口。当您需要私有方法时,只需将其转换为其他接口。

package some.exposed.package;

public interface PublicRenderable {
    public void publicRenderableMethod();
}



package some.package.you.dont.expose;

public interface PrivateRenderable {
    public void privateRenderableMethod();
}

public class RenderObject implements PublicRenderable, PrivateRenderable {
    public void publicRendereableMethod() {
        // implementation
    }

    public void privateRenderableMethod() {
        // implementation
    }
}



package some.exposed.package;    

public class PublicRenderObjectFactory {
    public PublicRenderable getRenderable() {
        return new RenderObject();
    }
}

您的List可以是List<PrivateRenderable>

答案 1 :(得分:1)

不幸的是,没有办法在接口中使用受保护的方法。界面中的所有方法都是隐式 publicabstract。任何偏离该模式的尝试都不会编译。

以下三种方法尽管外观相同但隐含相同。

public abstract void doSomething();
public void doSomething();
void doSomething();

但是,如果您声明任何明显与上述内容相矛盾的内容,则无法编译。例如;

protected abstract void doSomething(); // Does not compile
public final void doSomething(); // Does not compile

一个简单的解决方案可能是让抽象类以某种方式适合该法案。您可以尝试使用AbstractMovableObject,而您的新AbstractRenderableObject类都会扩展具有此受保护update()方法的第三个类(例如AbstractUpdatableObject)?这样他们就会成为BE-A AbstractUpdatableObject,但是它们之间的关系非常有限(不会超过他们实现相同界面时的情况),甚至可能有update();的不同实现。

答案 2 :(得分:1)

在界面中无法创建除公共功能之外的任何内容。

您可以轻松地在抽象类中实现受保护的函数,正如您所说的那样。你说这是不可能的,因为你的一些课程必须扩展一个不相关的课程。

因此,将受保护的方法放入RenderComposer类,这样可以composition,因此可以根据需要扩展多个类

这样的事情:

public class RenderComposer  {  //DOES NOT implement Renderable
   public RenderComposer()  {
   }
   public void update_4prot()  {
      //...
   }
}
public class SomeRederMover extends AbstractMovableObject implements Renderable  {
   private final RenderComposer renderer;
   public SomeRederMover()  {
      renderer = new RenderComposer()
   }
   protected void update()  {
      renderer.update_4prot();
   }
}