Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing a list of base type with children

Tags:

java

oop

I have a base class ShapeManager with a list of shapes which I want to enumerate(). Then there is a specialization ColoredShapeManager which wants to process specialized ColoredShapes instead of Shapes:

+----------------+      +-------------------------------------+
| Shape          |      | ShapeManager                        |
|----------------|      |-------------------------------------|
| + id: int      |      | # shapes: List<Shape>               |
|                |      |                                     |
|                |      | + ShapeManager() {                  |
|                |      |     shapes.add(new Shape());        |
|                |      |   }                                 |
|                |      |                                     |
|                |      | + abstract void enumerate() {       |
|                |      |     for (Shape s: shapes) {         |
|                |      |        // use s                     |
|                |      |     }                               |
|                |      |   }                                 |
+----------------+      +-------------------------------------+
         ^                              ^
         |                              |
         +                              +
+----------------+      +-------------------------------------+
| ColoredShape   |      | ColoredShapeManager                 |
|----------------|      |-------------------------------------|
| + color: int   |      | + ColoredShapeManager() {           |
|                |      |     shapes.add(new ColoredShape()); |
|                |      |   }                                 |
|                |      |                                     |
|                |      | + abstract void enumerate() {       |
|                |      |     for (Shape s: shapes) {         |
|                |      |       // use (ColoredShaped) s      |
|                |      |       // will fail for Shapes       |
|                |      |     }                               |
|                |      |   }                                 |
+----------------+      +-------------------------------------+

I am unsure whether ShapeManager should share shapes: List<Shape> with its children This seems flawed since ColoredShapeManager.enumerate() wants to process ColoredShapes. Hence it would cast the elements, yet some elements (those added by the base class) are of type Shape and the cast would fail.

That is:

  • Both types of shape end up in the list shapes.
  • enumerate() in the child manager should have access to ColoredShape.

Should I rather split the list and create private lists in each of the two managers? Then enumerate in the child would only iterate over "its" type of shapes and call the parent's enumerate() at the start/end.

like image 738
Micha Wiedenmann Avatar asked Jan 09 '13 17:01

Micha Wiedenmann


People also ask

Can parent and child classes have the same data member in Java?

Parent and Child classes having same data member in Java. The reference variable of the Parent class is capable to hold its object reference as well as its child object reference. In Java, methods are virtual by default (See this for details).

What are the different types of bases?

Types of Bases Strong base – It is a compound that has an ability to remove a proton from a very weak acid. Or they completely dissociate into its ions when in water. Examples are potassium hydroxide (KOH), sodium hydroxide (NaOH).

Where do the SP base types come from?

These Base Types come from the SPBaseType enumeration. Obsolete. Use 0 for discussion boards. These List Definitions come from the SPListTemplateType enumeration.

Why can't a child class access its child class members?

The reference holding the child class object reference will not be able to access the members (functions or variables) of the child class. It is because compiler uses special run-time polymorphism mechanism only for methods. It is possible to access child data members using parent pointer with typecasting.


2 Answers

You can add the shape type as the "type parameter" for your manager classes. So basically, ColoredShapeManager can extend ShapeManager<ColoredShape> and this T will be the type of your internal List data structure. Also, if your ColoredShapeManager doesn't do anything specific with the ColoredShapes, I would argue that it doesn't even need a new class. But then again it depends on the way you are structuring your app/design.

like image 129
Sanjay T. Sharma Avatar answered Oct 11 '22 04:10

Sanjay T. Sharma


Would the visitor pattern suit you here?

Shape

public void doSomething(ShapeManager) {
    ...
}

ShapeManager

abstract void enumerate() {
   for (Shape shape: shapes) {
       shape.doSomething(this);
   }
}

Then you wouldnt need to know the type and each shape derivative could have its own implementation.

like image 30
TedTrippin Avatar answered Oct 11 '22 04:10

TedTrippin