1

So I'm trying to make an array of (different) objects (one of those defined in the 'Triangle' class), after messing around with it for a while, this is what I've got:

public class ShapeContainer {

    private Object objects [];
    private int _size;
    public static final int init_size = 3;

    public ShapeContainer(ShapeContainer other){
        this.objects = new Object[other.objects.length];
        this._size = other._size;
        for(int i=0; i<_size ;i++){
            if (other.objects[i].getClass().equals(Triangle.class)){
                this.objects[i] = new Triangle(other.objects[i]);
            }
        }   
    }
 }

For that to work I've made a new constructor in the Triangle class(note: Triangle is built out of 3 Point objects: Point p1, Point p2, Point p3. Every Point object is built out of 2 double variables: x,y):

public Triangle (Object obj){
        this.p1 = new Point(obj.p1);
        this.p2 = new Point(obj.p2);
        this.p3 = new Point(obj.p3);
    }

And now the problem is that I can't refer to obj.p1/obj.p2/obj.p3 because "Object obj" isn't recognized as a Triangle object.

So basically, is there a way to make a generic Object recognized as a specific object? If not, how'd you approach this?

12
  • Use the actual type (Triangle) for your array variable. If you need to hold multiple different types of shape, create a Shape interface or abstract class and use Triangle extends Shape. Commented Jan 13, 2014 at 12:31
  • 1
    Your total approach is off. You should not be using Object type at all. Why not use Point instead? Commented Jan 13, 2014 at 12:31
  • You're trying to define the copy constructor in a wrong way. Just use Triangle for your array and you'll be fine. Or define an interface (or an abstract class) and implement/extend those. Also check the instanceof operator (your if conditions is a bit weird). Commented Jan 13, 2014 at 12:36
  • When you use a superclass reference to an object and you wish to access the methods and fields of the subclass you need to do a "cast". This is quite simply (TheSubclassName)theSuperclassReference. (Just don't fall into the trap of believing that a cast "converts" an object from one type to another. The object must already be the cast-to type.) Commented Jan 13, 2014 at 12:37
  • @HotLicks: Quite simple an quite dangerous. I'm betting that the OP wants to use bounded generic types. Generics are often useful for eliminating dangerous casts and for allowing for compile-time type checking and error catching. Commented Jan 13, 2014 at 12:45

1 Answer 1

1

There's a way, although it's usage is not very clean in my personal opinion. here it is

public Triangle(Object obj){
  if (obj instanceof Triangle){
      Triangle other = (Triangle) obj;
      this.p1 = new Point(other.p1);
      this.p2 = new Point(other.p2);
      this.p3 = new Point(other.p3);
  }
...
}

Why do I think this is not very clean? Well for starts I have no idea what to do if the object is not a Triangle. You'd have to figure that out, meaning what would you do if that constructor receives an object which is not a Triangle? Throw an exception? Not sure... This normally doesn't happen in methods such as equals where the instanceof is used often, because then you know you just return false.

However, at least you know how you can "recognize an object as triangle".

Hope this helps

Sign up to request clarification or add additional context in comments.

5 Comments

Well, that constructor won't receive that object if that's not a Triangle, meaning that I'd be able to make the exception outside the constructor. And yes, knowing how to recognize generic objects as specific ones did help a lot, so cheers :)
@MrGuy: Why don't you make it a public Triangle(Triangle obj) in the first place?
@DarkDust: Because that constructor wouldn't accept an Object for an input, only a Triangle (note that the constructor "public Triangle(Object obj)" that I wanted to use is added in addition to the already existing "public Triangle(Triangle obj)"
But if you know you only want to feed it Triangle objects, it's not a good idea to fight the type system like that. Check the type before calling the constructor and let the caller do the cast. After all, the call doesn't make any sense if you feed it something that is not a Triangle. That information is lost if you create a constructor that accepts anything.
(If I chose to stick the the answer given and not simply change it to be used with casts - just hinting that I know the whole thing is wrong), There'd be other constructors (like the one in Triangle) in the other sub-classes (Rectangle, Circle etc) so that each different type of object will have a different 'if' that'll send it to a different sub-class

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.