Search code examples
javaoopclassloader

How do I store the type of a class for use later in Java?


I have the following type:

public class Vehicle { ... }

The vehicle is instantiated by a user action. Think of it as an invention game, a user can create any type of vehicle he/she wants. For each object of the vehicle, I need to log the status of the object on a regular basis. So I have the following classes:

public abstract class Log { ... }
public class LogTyre extends Log { ... }
public class LogHandle extends Log { ... }
public class LogBrake extends Log { ... }
public class LogEngine extends Log { ... }
...etc...

An added complication is that each vehicle will have a different set of logging requirement. For example, a bike type vehicle will not require the LogEngine object.

So during my instantiation of the Vehicle I need to store the class types for the type of log the vehicle requires. So when it is time to perform a log, the logger will be able to instantiate the necessary logging class for that particular vehicle. How can I achieve this in Java? Or maybe just in OOP in general.

Any help will be appreciated, thank you.


Solution

  • I'm not sure I correctly understand your problem. But, with the hint by Hovercraft Full of Eels, the following code is written. You may add additional types of logs. Hope this helpful.

    import java.io.PrintStream;
    import java.util.ArrayList;
    
    public class Logger {
        public static void main(String[] args) {
            // creating vehicles
            Vehicle[] vs = { new Vehicle("Bike"), new Vehicle("Car") };
    
            // adding logs of different type
            vs[0].addLog(new LogTyre("Slim"));
            vs[1].addLog(new LogTyre("Wide"));
            vs[1].addLog(new LogEngine("Lean burn"));
    
            // maintaining logs
            Logger logger = new Logger();
            for (Vehicle v: vs)
                v.writeLog(logger);
    
            // printing logs
            for (Vehicle v: vs)
                v.printLogs();
        }
        public void write(Log log) {
            System.out.printf(".. writing to %s.%n", log.name());
            // You may write different logs depending on the log types using common methods
        }
    }
    
    class Vehicle {
        String type;            // vehicle type
        ArrayList<Log> logs;    // logs to be maintained
        public Vehicle(String type) {
            this.type = type;
            logs = new ArrayList<Log>();
        }
        public void addLog(Log log) {
            logs.add(log);
        }
        public void writeLog(Logger w)  {
            for (Log log: logs)
                log.accept(w);
        }
        public void printLogs() {
            for (Log log: logs) {
                log.print(System.out);
            }
        }
    }
    
    abstract class Log {
        protected String name;  // common fields
        // accepting the visitor
        public void accept(Logger logger) {
            logger.write(this);
        }
        // common methods for maintaining logs
        public abstract String name();
        public void print(PrintStream ps) {
            ps.printf("[Log: %s]%n", name());
        }
    }
    
    class LogTyre extends Log {
        public LogTyre(String name) {
            super.name = name;
        }
        public String name() {
            return name+" Tyre Log";
        }
    }
    
    class LogEngine extends Log {
        public LogEngine(String name) {
            super.name = name;
        }
        public String name() {
            return name+" Engine Log";
        }
    }
    

    This key of the above code is to pass the Logger to the Log using accept method. Then this accept method will invoke the appropriate write method of the logs of various types.