How can i build a system that achieves, what protected methods in interfaces would do?

StackOverflow https://stackoverflow.com/questions/22560454

  •  18-06-2023
  •  | 
  •  

Question

I'm building a little lwjgl library.

I have a RenderController, containing all the render objects AND other objects which are Renderable - so I took an Interface, called Renderable - containing the methods render() and. beforeRenderUpdate(). The problem is: the user of the library shouldn't be allowed to call RenderObject#update, because I want the lib to manage the rendering alone. But I want the user let have instances of this classes, because they sometimes extend AbstractMovableObject, and the user has to move them or request a uniform update. So, the option to create an abstract class containing the render method isn't possible. The advantage of an interfacr would be, I had one list in RenderController, objects <Renderable>(x).render().

But I don't want to have this render method public. What can I do now? As I sad, an abstract class isn't possible because this classes are extending something else.

Was it helpful?

Solution

Unfortunately there is no way to have protected methods in an interface. All methods in an interface are implicitly public and abstract. Any attempt to deviate from that pattern will not compile.

The following three methods are implicitly identical despite their appearance.

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

If however, you declare anything that explicitly contradicts the above, it will not compile. For example;

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

A simple solution might be to make an abstract class fit the bill somehow. You could try having AbstractMovableObject and your new AbstractRenderableObject class both extend a third class that had this protected update() method (eg AbstractUpdatableObject)? That way they would both BE-A AbstractUpdatableObject, but would otherwise have a very limited relationship (no more than they would if they implemented the same interface) and could even have different implementations of update();.

OTHER TIPS

There is no way to create anything but public functions in an interface.

You can easily implement protected functions in an abstract class, as you've said. You say it's not possible because some of your classes must extend an unrelated class.

So put the protected method into a RenderComposer class, which facilitates composition, so multiple classes can effectively be extended as you wish.

Something like this:

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();
   }
}

You can take advantage of the I in the SOLID principles, the Interface Segregation Principle.

Use 2 interfaces, one for the public stuff and one for the private stuff. Only expose the object to your user as the public interface. When you need the private methods just cast it to the other interface.

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();
    }
}

And your List can be a List<PrivateRenderable>.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top