Search code examples
javaoverridingabstract-class

Is there an alternative for overwriting the abstract method in the example cited?


I'm having a question about the implementation of this example here: https://dev.grakn.ai/docs/examples/phone-calls-migration-java. We have an abstract method inside a nested abstract static class:

public class PhoneCallsCSVMigration {
    /**
     * representation of Input object that links an input file to its own templating function,
     * which is used to map a Json object to a Graql query string
     */
    abstract static class Input {
        String path;

        public Input(String path) {
            this.path = path;
        }

        String getDataPath() {
            return path;
        }

        abstract String template(Json data);
    }
...

Later on, the abstract method template(Json data) is overridden with the aim of obtaining a graqlInsertQuery:

inputs.add(new Input("files/phone-calls/data/companies") {
            @Override
            public String template(Json company) {
                return "insert $company isa company, has name " + company.at("name") + ";";
            }
        });

First of all, how is it even possible to instantiate something of the type Input? And secondly, where does the Json company come from? I want to split up the PhoneCallsCSVMigration class into several classes like Input, GraknHandler, QueryHandler etc., and I'm wondering how I can define the template for constructing a Graql insert query other than overriding the abstract class. Any help is highly appreciated.


Solution

  • Evidenty externally an Input child is created with a path and implementing template. Probably this object is passed to the surrounding class and it calls template passing Json data.

    The abstract method could just as easily be replaced by a Function<Json, String> but then that function would miss the path, so one could use BiFunction<String, Json, String>.

    You have to look where and when the path and Json come from. Here it seems a bit artificial. Instead of an static inner class as above, a traditional (very similar) pattern would be:

    abstract class A {
        public final void func() { // Some service offered by this class.
            B b = ...;
            C c = onFunc(b);
        }
    
        abstract protected C onFunc(B b); // Some requirement to implement.
    }
    
    • Here func is for users of A, a service.
    • And onFunc is for implementors of A to fulfill a specific requirement.

    So out of context as in your case is a bit weird or over-engineered. Just passing a callback function would seem to do.