0

I am trying to figure out how to use an object's methods when iterating through an ArrayList. However, there is a part of the question that I couldn't fit above, and it's that in the ArrayList, there are objects, lets call them Shoes, that inherit from, lets say Clothes. But there are also Shirts and Socks in this array, that also each inherit from Clothes. So the array is of type Clothes, in order to accommodate the different types of objects in it. Observe:

ArrayList<Clothes> list = new ArrayList<Clothes>();
list.add(shoe);
list.add(shirt);
list.add(sock);

And this works because they all inherit from Clothes. However, I am trying to iterate through this ArrayList and use each object's unique methods like so:

for(Clothes piece : list) {
...//something like piece.getShoeSize();
}

Say I wanted to print out the shoes' sizes when a button is pressed, or the colors of each of the socks when a different button is pressed. I am unable to do this because, in the for loop itself, it is only looking for things that are of type Clothes, but when I change Clothes to Shoes, it doesn't work either, because list is a list of type Clothes. I've tried casting piece as a shoe or shirt, depending on the result of the if-statement

if(piece instanceof Shoe) {
...//((Shoe) piece).getShoeSize();
}

But that doesn't work either. If you have any ideas, I would greatly appreciate the help.

EDIT: For clarity.

Here is the class hierarchy:

public class Clothes {
getColor();
}

public class Sock extends Clothes {
...
}

public class Shirt extends Clothes {
getSize();
}

public class Shoe extends Clothes {
getSize();
}

So my program has a JComboBox with various things inside it. It also has a JTextArea beneath it. What I am trying to get my program to do is print out something into the JTextArea depending on what option is selected in the JComboBox. So let's say there is an option SIZE in the JComboBox. When it is selected, I want all of the objects that are in list, that are also capable of performing the method getSize(), to perform the method getSize(), which prints out the size of the object (like XL or 10.5) to the JTextArea. Now, because the class Clothes does not have a getSize() method (because not all clothes have definitive sizes. For example, Socks), I am having issues. The list is of type Clothes, so in the for-loop, I must declare the type of object as Clothes. But the piece is therefore also of type Clothes, so when I try to run getSize() on it, it gives me an error, because Clothes does not have a method getSize() in it. However, some of the objects in list do have this method. So my question is how to access this method for objects in the ArrayList list which is of type Clothes.

17
  • Why do you check for instance of shoe, but cast to Shoe. Is this typo? Commented Mar 5, 2016 at 3:35
  • @KenBekov No it's not a typo. I'm checking to see if the object in list is of type Shoe, but then I must cast it to Shoe because 'piece' is of type Clothes, because of the for-loop Commented Mar 5, 2016 at 3:38
  • I mean, in your code snippet you use shoe starting with lower case, and Shoe starting with upper case. Different things. When you say 'doesn't work', what do you mean? Have you any exceptions? Commented Mar 5, 2016 at 3:43
  • Should this: piece instanceof shoe not be piece instanceof Shoe Commented Mar 5, 2016 at 3:43
  • What error message are you getting when casting to Shoe? Commented Mar 5, 2016 at 3:48

2 Answers 2

1

You could use inheritance to do this quite nicely!

public abstract class Clothes {

    public abstract void printTo(JTextArea out);
}

public class Shoes {

    private int size;

    public Shoes(int size) {
        this.size = size;
    }

    @Override
    public void printTo(JTextArea out) {
        out.println("Shoe size is: " + size);
    }
}

public class Socks {

    private String color;

    public Shoes(String colr) {
        this.color = color;
    }

    @Override
    public void printTo(JTextArea out) {
        out.append("Socks color is: " + color);
    }
}

Then, you can call it simply like:

JTextArea myArea = new JTextArea();

list.add(new Shoes(12));
list.add(new Socks("red with a dash of blue"));

for (Clothes piece : list) {
    piece.printTo(myArea);
}

And get something like:

Shoes size is: 12
Socks color is: red with a dash of blue

Here, Clothes has an abstract method named printTo that allows subclasses of Clothes, such as Shoes and Socks, to define how they want to print.

So in this case, Shoes will override printTo and print out the corresponding shoe size. This is defined by Shoes and allows direct access to all the information, such as size.

Socks defines printTo to print out the corresponding color. Once again, this is up to Socks to define what and how it is printed.

Now in the loop, it doesn't matter if the Clothes object is Shoes or Socks, they both inherit the printTo method from Clothes. This method is then invoking, leaving it up to the implementations of Clothes to determine what and how to print.


Java Inheritance - Oracle

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

13 Comments

The problem is that the method that I'm trying to access is not in the Clothes class, it is unique to the Shoes class.
@ipodfreak0313 Yes, and unless you are doing casting and instanceof checks (which has quite a bad code smell), abstraction like this is the way to go.
the method that I'm trying to access is something that the Shoe object did not inherit from Clothes.
@ipodfreak0313 do you intend to use the data within the for-loop? If so, this is still do-able but would require more work. This might also be an XY Problem where you are asking how to fix your attempted solution instead of solving the problem.
@ipodfreak0313 I feel like you've left out quite a bit of information, including what you actually intend to do with this (thus the XY). And as for what you say you want it to do - perform a certain method that is specific to them - something like I posted would do just that. And I'm 100% sure you can do it, you just need to be clearer with what you actually intend to do.
|
0

Ok I figured it out. The only thing I had to do was call

new Main();

inside of

public static void main(String[] args)

and put all of my code inside of Main(), and everything worked fine.

Comments

Your Answer

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.