1

I'm learning to code and currently I'm trying to clean up my massive code by finally learning classes. I'm telling you this just to give a heads-up my terminology might still be off :) :)

The situation

  • My code works with "layers" that will be drawn on top of each other
  • There are two types of layers: video layers and image layers.
  • Both types of layers are child from parent class "Layer"
  • They need to be run by creation order

The goal

I want to run a code for each item/object of the class.

current code

import java.util.*;

public class main  {

    public static void main(String[] args){


        // defining the objects
        LayerVideo item01 = new LayerVideo();
        item01.path = "import/01/";

        LayerVideo item02 = new LayerVideo();
        item02.path = "import/02/";

        LayerImage item03 = new LayerImage();
        item03.path = "import/03/";



        // here is the main goal:
        // to run/call each object from class "Layer"
        
        // "allLayers" does not exist, but that's what I don't know how to do.
        allLayers.forEach( item ->{
            System.out.println( item.path );
            // expected result in console:
            // import/01/
            // import/02/
            // import/03/
        });

    }

    public static class Layer {

    }

    public static class LayerVideo  extends Layer {
        public String path;
    }

    public static class LayerImage  extends Layer {
        public String path;
    }
}

Thoughts

  • How to get all excising objects from a class
  • If I have them, how to ID them?, by var name?
  • Could I sort/filter the objects in a loop?
7
  • First: learn about java naming conventions. Class names should go UpperCase. main obviously doesn't fit that rule. And it is also a bad idea to simply "re-use" names that already have a very distinct meaning. Commented Oct 22, 2019 at 12:49
  • Polymorphism is the right keyword. Google it and you will find your answer. Commented Oct 22, 2019 at 12:51
  • 2
    @momo I really dont see how that comment will help the OP. I think Tim is struggling with using a LIST or array to collect multiple objects of some class. That has nothing to do with polymorphism. Thus: I think your comment is highly misleading. Commented Oct 22, 2019 at 12:52
  • @GhostCat: He is already iterating over a collection. In a comment, he mentions: "allLayers does not exist, but that's what I don't know how to do". IMHO, he wants to create ONE layer collection and to do so, he should use Polymorphism. Commented Oct 22, 2019 at 12:57
  • yes, I'm pretty unclear :) Thanks for the feedback so far. I'll do some reading on your suggestions. Commented Oct 22, 2019 at 13:00

3 Answers 3

3

Two things:

  • consider to make your classes top level ones. So don't go public static class LayerVideo inside your Main class. If they are that important, the classes should each go into their own java file.
  • then learn about Java collections to organized object instances. You could define use an ArrayList for example.

Beyond that, the point is probably: if you want common things for two different classes, then your base class needs to have that, like:

public abstract class Layer {
   private String path; 
   public String getPath() { return path; }
   public void setPath(String newPath) { path = newPath; }

and then your subclasses simply inherit that behavior.

Then, you simply can add objects with that extend that base type to a collection:

List<Layer> layers = new ArrayList<>();
Layer layer = new VideoLayer();
layers.add(layer);
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I see where this is going. I should add the objects to a list/array from the start. I dive into that first thing. Thanks for your time!
just a question, can I also label/id the items in the ArrayList? So I can do something like layers.item2
I really hate ending with "thanks", but I really do appreciate it. Even with my code gibberish I got send in the right direction. Without it I would have kept focusing in the wrong direction. I'll start with the tutorials first thing tonight
@Tim No harm done. The key thing is to not confuse stackoverflow with programming school, and assuming that the people answering here are your tutors that work with you through all parts of your curriculum. Come with specific questions, and you will receive specific answers ;-)
0

So, with the help and pointers of @GhostCat I've came to the following working code:

main.java

public class main  {

    public static void main(String[] args){

        // debug to see amount of elements in list
        System.out.println( settings.layers.size() );

        // Aggregate with .forEach(), but will switch to .stream() to also be able to filter
        settings.layers.forEach( layer -> {
            System.out.println( layer.path );
            // do stuff
        });
    }
}

settings.java

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

public class settings extends main{

    public static List<Layer> layers = new ArrayList<>();

    static {
        layers.add( new LayerImage(true, "input/01/", new int[] {255,255,255} ) );
        layers.add( new LayerImage(false, "input/02/", new int[] {255,0,0} ) );
        layers.add( new LayerVideo(true, "input/03/", new int[] {0,0,255} ) );
    }

}

Layer.java

public abstract class Layer {

    boolean run;
    String path;
    int[] color;


    public Layer(boolean startRun, String startPath, int[] startColor) {
        run = startRun;
        path = startPath;
        color = startColor;
    }

}

LayerImage.java

public class LayerImage extends Layer {

    public LayerImage( boolean startRun, String startPath, int[] startColor) {
        super( startRun,  startPath,  startColor) ;
    }

}

LayerVideo.java

public class LayerVideo extends Layer {

    public LayerVideo( boolean startRun, String startPath, int[] startColor) {
        super( startRun,  startPath,  startColor) ;
    }

}

In the main.java I'll swap the aggregator .forEach() with .stream() later on. Sounds more flexible and to be able to filter the results in advance seems like a big advantage. (then I can also use the item.run to see if I want to run this layer).

Why is there a settings class? I want to be able to have ALL the settings and variables to set for the outcome in one file. This way I can (I think) quickly use different setting files. Maybe also change it to XML input later. Use a GUI or whatever. (You might think "ah, sweet summer child", I'll cross that bridge when I get there).

The Layer SuperClass will have around the 10 parameters/arguments in the constructor when finished. Feels a lot to change and maintaining for the SubClasses by passing it with super(); And later on make changes. What is I will have around, say, 20 SubClasses. Is there a more efficient way?

Any other pointers on what I can do better in this code above?

All in all a LOT learned today! Thanks everyone and special thanks to @GhostCat

Comments

-1

I personally create an static ArrayList from the object for every class and add the objects to it in the constructor (with list.add(this)).

Like:

public class Layer{
 static ArrayList<Layer> layerList = new ArrayList<>();
  public Layer() {
    layerList.add(this);
  }
}

2 Comments

This is only safe if you strictly separate creating layers and doing something with them. Otherwise concurrent code can observe unfinished objects. More on that here.
Vary helpfully. Thank you for this advice.

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.