简体   繁体   中英

Type-safe interface when instantiated/returned from enum (Java)

Suppose we have an Automobile object:

public interface Automobile {
}

We also have a couple of different cars (is-a), one with an auto transmission and one with a manual transmission:

public class FordExplorer implements Autmomobile {
    public static void shiftIntoPark() {
    }
}

public class Porsche911 implements Autmomobile {
    public static void shiftInto1stGear() {
    }
}

Now, let's say we have an enum Garage, which stores these Automobiles:

public enum Garage {
    FORD {
        public Automobile getCar() {
            return new FordExplorer();
        }
    }, PORSCHE {
        public Automobile getCar() {
            return new Porsche911();
        }
    };

    abstract public Automobile getCar();
    }

}

Is there a "best practice" for this implementation (or one similar to it) that is type-safe (ie so that the return type of the getCar() method for the FORD only includes the shiftIntoPark() method and, likewise, the return type of the same method for the PORSCHE only includes the shiftInto1stGear() method)?

The type returned by Garage.getCar is Automobile, it's not going to expose any of these park methods. Since the shift methods are static you're not going to get polymorphic behavior out of them, they have to be called on the specific classes.

It is likely you are expecting the thing using the Automobile to be too smart about how it's using the Automobile, thereby defeating the purpose of using an interface. The point of using interfaces or superclasses like this is so that the program can manipulate objects at a high level without caring about implementation details, letting the different object implementations take care of themselves. An analogous toy example might be an Automobile that exposed a park method, where that park method was implemented differently by the specific subclass according to its specific needs.

(Or alternatively get rid of the interface altogether, since driving a Mustang is not anything like driving a Corolla it might not make sense for them to share an interface.)

Interfaces and superclasses help provide a high-level interface and hide implementation details so they can be contained locally and don't leak out all over the rest of the program. Work out how you want the object to be used, which defines the interface you want to expose, and what you want the object to take care of on its own.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM