开发者

Java inheritence problem: going beyond the vtable

开发者 https://www.devze.com 2023-02-25 10:27 出处:网络
Here is the scenario: I have an interface A, 100 classes B0 ... B99 that implement only A and 50 classes C0, C2 ... C98 that extend B0, B2 ... B98.

Here is the scenario: I have an interface A, 100 classes B0 ... B99 that implement only A and 50 classes C0, C2 ... C98 that extend B0, B2 ... B98.

The B classes work with a MySQL database, doing various stuff on the tables. The C classes add extra logic to B classes (validations, privileges etc). The B classes are generated by a tool, while the C classes are written by a coder.

A client application will use the B classes and will not have access to C classes. When a method is called for a B object, the client will serialise the object and send it to a server application, along with the method name that is to be called.

The server will receive the B object and cast it as an A. However, the server would like to execute the method that was overridden in the C class if such a class exists, and the method from B otherwise. Normal behaviour would only execute the method from B.

How would the server be able to do that without having a huge SWITCH statement that would cast the received object to a C?

EDIT: 开发者_运维百科I am new to java and did not know what reflection could do. With a little help from google (this and this) I solved my problem. I can use dynamic casting for what I want to achieve. Thanks to everybody.


Assuming that each C class has a constructor or a static createFromSuper to create it from it's parent B (or from an A)...

You can create a FactoryClass where all available C's are registered. You can use reflection to get the parent of C you want to "replace", remembering each B.class->C.class mapping in a Map/Hashtable.

Then when you receive a B, you pass it to the Factory, which will return the same B object if it finds a mapping, or calls the constructor/createFromSuper returning the C.


That approach sounds really odd to me. Why don't you just provide commands (e.g. strings that define the command names) and register command objects for those commands? Then you just send over the command as well as some serialized parameters.

Edit:

From your description it seems as if the C objects would really be decorators to the B object. In that case they would not inherit from the corresponding B but take e reference to it and the server would then look up the decorators for the B passed (based on class for example, or any other identifier), create them (or just one) passing the B and then invoke the method on the decorator.

Much like BufferedReader decorating any Reader.


Well you have an object of runtime type B, and you are asking to call it as if it were an object of type C. This isn't really how inheritance works; you cannot downcast to C unless it was originally created as a C, because in general, it doesn't have all the fields of C.

I am guessing your C classes do not add any additional fields to a B (if they did, your question wouldn't make sense). Since they don't add any additional fields, then I can see how it would make sense to treat them as a C, but there isn't a really good way to do it. I would say:

  1. Why are there Bs and Cs in the first place? Why not just have B classes, with all the privileges, etc, and use that?
  2. Failing that, I suppose you could use reflection. Write some generic code that takes any of your B class objects, constructs a new corresponding C object, and copies over all of the fields.
0

精彩评论

暂无评论...
验证码 换一张
取 消