0

I have a number of types that all relate to each other in terms of them being 'derived' from one another. I'd need a way to do is relationships, which made me initially think of classes, but I realized that other than the is relationships, there would be no reason to use classes as each 'type' of data function the exact same way. I'd also thought of enums, but since there is no way to extend or inherit from enums it was a poor choice.

For context (this being my specific example): I have a number of different kinds of resources that all are 'types' so that they can be used in conjunction with an int to denote how much of that resource is available. I have several different kinds of these resources, such as foods, metals, building materials etc. Within the food category would be something like wheat or corn; under metals would be copper, iron, gold etc. Since all of these are still just 'resources' and have no actual functionality other than typing, it seems pointless to use classes and OO inheritance.

How would I implement this kind of data type without resorting to using classes?

  • A class that contains an enum member? – Oded Mar 7 '14 at 14:09
  • Using classes to model type differences is often a good idea even when the set of fields is structurally equivalent. Why don't you want to use classes? Are you afraid of slowness? – Kilian Foth Mar 7 '14 at 14:09
  • @KilianFoth Slowness isn't really an issue here, but if possible I'd like to keep memory usage down. It just seems rather pointless to have classes that all inherit from one another without actually adding on if there's another way to do it. – PixelArtDragon Mar 7 '14 at 14:12
  • I suppose the root of the issue is: Does it make sense to inherit from a class when you're not adding any functionality, and what's an alternative to this? – Phil Mar 7 '14 at 14:16
3

If there are no functions to inherit, composition of structs may be more favorable than class inheritance. The concept of "composition over inheritance" may apply here, see:

Wikipedia

Popular SO Answer to this issue

Although the above examples use classes, an alternative implementation could use structs:

Composition with C structs

  • If I'm understanding this correctly, what I could do is have each of the different instances of the one class have 'parent' instances, and to check the relationships I'd just need to compare the objects and their 'parent'? – PixelArtDragon Mar 7 '14 at 14:21
0

What you described is very much possible without checking is relationships.

An object oriented design should rely on interfaces, not implementations. That means, code like this:

if (o is Derived1)
{
    do_something_with_derived1(o);
} 
else if (o is Derived2)
{
    do_something_with_derived2(o);
} 

Should be turned into

o.do_something_virtual(context);

Essentially, you move the responsibility of "doing something" from the caller to the callee. The caller only triggers this action. The callee knows its own type and can act accordingly. If there is any context on the calling site that you would use in the operation, you pass that as a parameter.

The key here is the virtual method, which allows for a dynamic dispatch. This removes the strong dependency to each implementation and "type checking" boilerplate on the calling site. The calling site can even call future implementations.

Another possible approach is a data driven design. Entity Component systems are a flexible solution that can be used to avoid complicated class hierarchies when each base class would only add a little bit of functionality (in your example: the kind and amount of resource).

  • The whole point of this is that there are no different functionalities; each type functions exactly the same, but need still to have a kind of hierarchy. The amount of the resource isn't actually stored within the class – PixelArtDragon Mar 7 '14 at 14:28
  • 1
    @Garan there is actually new/different functionality, but misplaced in the calling site. You would write class-specific code outside the class, which is an antipattern. What I'm suggesting is the object oriented way of designing it. – Tamás Szelei Mar 7 '14 at 14:39
  • @Garan The point of the answer is "Eliminate your need for is relationships by refactoring your design a bit." If you eliminate your need for is relationships, then type hierarchy becomes much less necessary. – Phil Mar 7 '14 at 14:39
  • As for the amount being stored outside the class: you could pass that as a parameter, but maybe it would make sense to store in the class? Without knowing your requirements in more detail, it's hard to tell. – Tamás Szelei Mar 7 '14 at 14:40
  • @TamásSzelei The thing is, in a lot of cases the actual amount isn't necessary or even applicable to the situation. And while I could store the amount, it doesn't solve the very fundamental question of having an inheritance structure where new code isn't added. – PixelArtDragon Mar 8 '14 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.