2

I have a class:

class Cube
{
 public string Name;
 public string TexturePath;
}

And another class that inherits Cube

class DrawableCube : Cube
{
 public Texture2D Texture;
 public Shader Shader;
}

Suppose I have a collection of Cube that I want to turn into DrawableCube. Without just creating a constructor that takes a Cube as an paramter and copies all of the attributes across, how can I make a copy of a Cube with the resulting type DrawableCube?

asked Apr 24, 2011 at 21:06
5
  • 5
    This code is evil, you declare two public members with the same name except for capitalization that are different types... Commented Apr 24, 2011 at 21:12
  • 2
    I think what you are talking about is the removal of boilerplate. To my knowledge, its not possible to do it without copying all the values over; Why are you doing this in the first place? Commented Apr 24, 2011 at 21:14
  • @mathepic Sorry about that, I typed it in to hastily. Fixed Commented Apr 24, 2011 at 21:18
  • @mathepic because I have an array of cubes, and I want to turn them into drawable cubes. Maybe my design is flawed? Commented Apr 24, 2011 at 21:22
  • can you not create DrawableCube's in the first place? Or just add the drawable cube stuff to the cube class. Commented Apr 24, 2011 at 21:24

4 Answers 4

6

IMHO the best solution here is not to inherit DrawableCube from Cube at all, but let the UI class DrawableCube keep an internal reference to the data class Cube. Cube, however, should probably be designed as an immutable class. This way DrawableCube will need a constructor taking a Cube, but you don't have to copy all of it's attributes, you can just store the given reference:

class DrawableCube : 
{
 private myCube;
 public DrawableCube(Cube c)
 {
 myCube=c;
 } 
}
answered Apr 24, 2011 at 21:22

3 Comments

A DrawableCube is almost certainly a Cube, so this breaks OOP polymorphism.
I think you're right about this. I can probably live without the inheritance here. To Quote GLaDOS in Portal 2, "The best solution is usually the easiest"
@mathepic: the question to ask here if polymorphism is really needed here for Cube and DrawableCube. If that's the case, they should have a common base class or interface ICube. This will result in the Proxy design pattern (en.wikipedia.org/wiki/Proxy_pattern), where DrawableCube is a proxy for Cube.
1

Warning: The following solution is ugly but it does what you want.

Make Cube take a single parameter of type CubeInformation in its constructor, and that is its only member (it is private). It simply sets the CubeInformation. It then provides properties for the stuff in that struct.

Let CubeInformation be a struct that contains the data for a Cube.

Let DrawableCube have a constructor that takes a Cube and copies over the CubeInformation struct from the Cube.

Wallah. If someone has to add more data to the Cube, they add it to the CubeInformation struct and implement the properties in Cube. No maintenance is necessary in DrawableCube.

answered Apr 24, 2011 at 21:23

Comments

1

If you want to turn collections of Cube into a collections of DrawableCube, then maybe inheritance is not the right tool.

Give aggregation a try:

class DrawableCube //: Cube
{
 public Cube TheCube { get; private set; }
 public DrawableCube (Cube c) { TheCube = c; }
 public Texture2D Texture;
 public Shader Shader;
}
answered Apr 24, 2011 at 21:27

Comments

0

Since you don't want a constructor, I guess the only other option is with a factory pattern.

answered Apr 24, 2011 at 21:09

5 Comments

Well a constructor is fine, but I don't want to manually copy the values across. (What if someone decides to add new fields to cube?)
Your whole design seems to be the problem.
Do you think I should do this without inheritance then, and create a DrawableCube class that just contains a Cube?
Why do you need to separate "Cube" and "DrawableCube"?
Because Cube comes from another assembly, which can't have a reference to OpenGL.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.