0

I am having the next code arhitecture:

  • class candybox with arguments flavor and origin which is the parent class for classes: Lindt, Baravelli and ChocoAmor which will have as a plus arguments: height, width(depending of the box)
  • class CandyBag which needs to contain an Arraylist that will represent a gift containing 1 candybox of type Lindt, 1 candybox of type Baravelli and 1 candyboxe of type ChocoAmor. Now my problem is that I do not know how to populate the arraylist from class candybag with objects from the 3 classes: Lindt, Baravelli and ChocoAmor.

I thought of this:

import java.util.*;
class CandyBag extends CandyBox{

ArrayList<CandyBox> candybag = new ArrayList<CandyBox>();


CandyBox Austria_cherry = new Lindt(20, 5.4, 19.2); 
Candybox Italy_grape = new Baravelli(6.7,8.7);
Candybox France_coffee = new ChocAmor(5.5);

 
candybag.add(Austria_cherry);
candybag.add(Italy_grape);
candybag.add(France_coffee);


public void printArray(candybag){
 for(String item: candybag){
  System.out.println(item);

} }

And then in main class just to create a candybag object and call printArray method: CandyBag cadou = new CandyBag(); cadou.printArray(candybag); //i do not know exactly how to pass the arraylist from other class as parameter

Can you help me with this, how to print the arraylist with the 3 boxes?

Aled
  • 1
  • 1
    You don't need to pass any list into that method. It's an instance method and therefor can access the field `ArrayList candybag` of the instance the method is called on. – OH GOD SPIDERS Jul 06 '23 at 13:33
  • oh, and you can't just start writing method calls like `candybag.add(Austria_cherry);` into your class body. Those lines need to be inside a method or better yet a constructor. – OH GOD SPIDERS Jul 06 '23 at 13:34
  • What are the fields of each class that you pass into their constructor? Can you add the implementation of those classes for me to get a better idea of what you are trying to achive? – Kozmotronik Jul 10 '23 at 18:57

2 Answers2

0

I think you need to override the toString() method of each class to return the desired text. Also, the elements of candybag list are not string type.

for (CandyBox item: candyBag) {
    System.out.println(item.toString());
}
Enis Mustafaj
  • 33
  • 1
  • 6
  • 1
    `System.out.println(item.toString());` is not necessary and pretty much all you do is introduce a potential NullPointerException. As the javadoc of [println(Object x)](https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html#println-java.lang.Object-) says the method will call [String.valueOf(x)](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#valueOf(java.lang.Object)) : *"if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned."* - So toString is already called by `System.out.println(item);` – OH GOD SPIDERS Jul 06 '23 at 13:43
0

Your question is a little unclear and lacks all relevant codes. However I'll try to answer it as far as I understand.
What I understand of your goal is: You want to create inherited classes of CandyBox and finally a CandyBag class each of which can be represented as string in order to be able to print. Correct me if I get it wrong.
Well, I would suggest you to use Object.toString by extending the Object class and overriding the toString method.
Since I don't know the properties of the inherited classes like Lindt I just added height and width properties to be able to implement this example. So let's get into it...

First we would implement the base class CandyBox. Normally it should inherit from the Object class implicitly. But in case of it don't, you should extend it explicitly. In the base class we will override the toString method to implement our logic so that it can create a string containing its name and its properties. But note that we declare an abstract method named getName so that inheritors of this class implement this method for getting their own name. Hence the class itself must be an abstract class as well.

public abstract class CandyBox {
    
    private final double height, width;
    
    public CandyBox(double height, double width) {
        this.height = height;
        this.width = width;
    }
    
    public abstract String getName();
    
    public double getHeight() {
        return height;
    }
    
    public double getWidth() {
        return width;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(getName());
        sb.append(" { [height:").append(getHeight()).append("], [width:").append(getWidth()).append("] }");
        return sb.toString();
    }
}

Now that we have our base class we will create its inheritors Baravelli, ChocoAmor and Lindt respectively.

public class Baravelli extends CandyBox {
    
    public Baravelli(double height, double width) {
        super(height, width);
    }
    
    @Override
    public String getName() {
        return getClass().getSimpleName();
    }
}


public class ChocoAmor extends CandyBox {
    
    public ChocoAmor(double height, double width) {
        super(height, width);
    }
    
    @Override
    public String getName() {
        return getClass().getSimpleName();
    }
}

public class ChocoAmor extends CandyBox {
    
    public ChocoAmor(double height, double width) {
        super(height, width);
    }
    
    @Override
    public String getName() {
        return getClass().getSimpleName();
    }
}

All inherited from the CandyBox class and its toString implementation. So these 3 classes know how to generate their string representation.
Let's proceed and create the CandyBag class which will inherit from the CandyBox class as well but override the toString method to implemnt it for its needs.

import java.util.ArrayList;
import java.util.List;

public class CandyBag extends CandyBox {
    
    private final List<CandyBox> candyBoxes = new ArrayList<CandyBox>();
    
    public CandyBag(double height, double width) {
        super(height, width);
        candyBoxes.add(new Lindt(3.2, 9.2));
        candyBoxes.add(new Baravelli(3.3, 10.4));
        candyBoxes.add(new ChocoAmor(3.4, 11.6));
    }
    
    @Override
    public String getName() {
        return getClass().getSimpleName();
    }
    
    @Override
    public String toString() {
        String s = super.toString();
        StringBuilder sb = new StringBuilder(s);
        sb.append("\n").append(getName()).append("'s contents: { \n\t");
            for (int i = 0; i < candyBoxes.size(); i++) {
                CandyBox cb = candyBoxes.get(i);
                sb.append("[").append(cb.toString()).append("]");
                String ending = i < candyBoxes.size()-1 ? "\n\t" : "\n";
                sb.append(ending);
            }
            sb.append("]}");
            return sb.toString();
    }
}

Here it has three fixed candy boxes that created once when it is instantiated (in its consructor method). It also overrode the toString method because it has to add its candy content to its string representation.
The 99% of the job is done so far. Now it is time to test it. Let's test it in a main class, let's create 1 CandyBag object and print its string representation.

public class MainClass {
    
    public static void main(String[] args) {
        System.out.println("Here we go...");
        CandyBag candyBag = new CandyBag(4, 20);
        System.out.println(candyBag.toString());
    }
    
}

See the output:

Here we go...
CandyBag { [height:4.0], [width:20.0] }
CandyBag's contents: { 
    [Lindt { [height:3.2], [width:9.2] }]
    [Baravelli { [height:3.3], [width:10.4] }]
    [ChocoAmor { [height:3.4], [width:11.6] }]
]}

You can play with the toString implementation to change the string representation form for your convenience. Go ahead and try this implementation and let me know if you hit your goal or fail for some reason.

Kozmotronik
  • 2,080
  • 3
  • 10
  • 25