inheritage with classes

Started by
18 comments, last by alvaro 9 years, 6 months ago

If I understand correctly, you want an object that has a method `show' which will call `show' on both the character and the tiles. You can do that by having a simple class with references or pointers to the character and the tiles and whose `show' method calls the `show' method for the character and the `show' method for the tiles.

If you want to make your class more general, so you can give it any number of things to call `show' on, you can do that by using inheritance and polymorphism. You make a class (or interface) called Showable, from which both the character and the tiles inherit. You can then have an object that has a container of Showables and whose `show' method calls the `show' methods on all the objects it contains. That would be a much more natural use of inheritance.

Advertisement

If I understood correctly, you have the following procedures:

-Show character

-Show all the tiles

But you need:

-Show all the tiles and the character

To handle depth sorting.

A flexible solution would be to add a new depth sorting layer between the two classes you have and the actual rendering. So each class issues 'render requests' for tiles/character that includes the depth information (as in depthSortingRenderer.addSurface(x,y,depth, etc...) ), and then at the very end you sort them by depth and render them to screen in order.

Another approach would be to write up a new procedure that can render both tiles and characters in one go, but I couldnt decide where the logical place for that would be. Inheriting from both character and tile renderer is not it (its neither a tile renderer nor a character!). Inheriting from the tile renderer doesnt really keep it as a tile renderer anymore. Maybe you could modify the tile renderer so it renders a single layer at a time (tileRenderer.showLayer(N)) which would allow you to throw the character rendering in the right spot? Or anything like that (like .showAllTilesBetweenDepths(mindepth,maxdepth), or .renderAllTilesButCallThisCallbackJustBeforeRenderingThisDepth(callback lambda func,depth) so you can draw the character in the callback)

Dont really program much at all so not very good at code structuring issues :P

o3o

If I understand correctly, you want an object that has a method `show' which will call `show' on both the character and the tiles. You can do that by having a simple class with references or pointers to the character and the tiles and whose `show' method calls the `show' method for the character and the `show' method for the tiles.

If you want to make your class more general, so you can give it any number of things to call `show' on, you can do that by using inheritance and polymorphism. You make a class (or interface) called Showable, from which both the character and the tiles inherit. You can then have an object that has a container of Showables and whose `show' method calls the `show' methods on all the objects it contains. That would be a much more natural use of inheritance.

I made a class call render which is inherited by Class A and Class B. I moved all the private variables from both class to the Render class and made them all protected. Am I getting closer to the solution? I didn't quite understand everything you said.

I made a class call render which is inherited by Class A and Class B. I moved all the private variables from both class to the Render class and made them all protected. Am I getting closer to the solution? I didn't quite understand everything you said.


Nope. I'd argue that you're going in the complete wrong direction.

class A {
public:
  void render();
};

class B {
public:
  void render();
};

class C {
  A* a;
  B* b;

public:
  void render() {
    a->render();
    b->render();
  }
};
Absolutely no inheritance is needed.

Prefer _aggregation_ over _inheritance_ (C in this case "aggregates" A and B, but does not inherit from either of them, nor do they inherit from C).

In general, use inheritance when you need _is-a_ semantics. E.g., Derived _is a_ Base. Otherwise, use a _has-a_ relationship, e.g. Composite _has a_ Component. This even works for shared functionality. If A and B both have the same renderable methods and data you can move those off to a RenderHelper type and then include that as a member in A and B rather than inheriting from it. Then you can also add even more helpers to A and B without ending up down the rat hole that is multiple inheritance.

Sean Middleditch – Game Systems Engineer – Join my team!

I do not need inheritage. It would be nice if I did since it would fulfill another personal quota for the project but I do not need it.

This is why I love to use component based architectures ;3!

View my game dev blog here!

Hmmmm This doesn't seems to be what I'm trying to do. I need the child class to do more than print, I need it to print in a specific way.

can child class can inherit from 2 parent classes?

It seems you have decided to implement things a different way, but in my example each child class would be responsible for defining the specific way that class should print. The ArtRenderer class only defines the functions the child classes are required to implement (in this case, the show() method). The specifics of how each child class implements the show method is not restricted in any way. One class could render things as ASCII art, and the other through OpenGL. But, after reading through your additional posts, inheritance isn't really needed to solve your problem.

@SeanMiddleditch

Aggregation is fine until you have lots of different classes that all have to implement a show function. In your example, with aggregation alone you would have:


class A {
public:
   void render();
};

class B {
public:
   void render();
};

class C {
public:
   void render();
};

class C {
public:
void render();
};

class D {
public:
void render();
};

class E {
public:
void render();
};

class F {
A* a;
B* b;
C* c;
D* d;
E* e;
// and so on

public:
void render() {
a->render();
b->render();
c->render();
d->render();
e->render();
// and so on
}
};

It's pretty concise if anything that can be rendered implements a Renderable interface. Then anytime you need to hold several Renderable objects, you can just refer to them through the interface type. For example, you can then store all of your Renderable objects in a data structure (e.g. maybe you want to keep things in a tree to optimize collision detection) - which essentially aggregates all of the objects. Saves you from having to deal with the ugliness of templates.

Regardless, can you post some links to data-driven programming tutorials? It's useful stuff to know about.

I do not need inheritage. It would be nice if I did since it would fulfill another personal quota for the project but I do not need it.

Never ever ever ever ever ever use a programming pattern just to use it. Most of the time you will be making the wrong decision. Code should evolve from your needs, not the other way around.

"So there you have it, ladies and gentlemen: the only API I’ve ever used that requires both elevated privileges and a dedicated user thread just to copy a block of structures from the kernel to the user." - Casey Muratori

boreal.aggydaggy.com

I do not need inheritage. It would be nice if I did since it would fulfill another personal quota for the project but I do not need it.

Never ever ever ever ever ever use a programming pattern just to use it. Most of the time you will be making the wrong decision. Code should evolve from your needs, not the other way around.

Oh yeah! Answer me this, how do I know when I need it?

Oh yeah! Answer me this, how do I know when I need it?


Don't worry about it. One day you'll be staring at some problem and you'll realize inheritance ("inheritage" is not a word) is precisely what you need to solve it. If that day never comes, maybe inheritance wasn't important to begin with.

This topic is closed to new replies.

Advertisement