I'm creating a abstractFactory class and I want to be able to send the concrete factory as a parameter. This way I can remove the if/else chain inside my abstract class.
My problem is I'm not sure how to typecast it back to the concrete class within my abstract class in order to call the createVehicle() method.
car = UniversalVehicleFactory.getFactory().createVehicle(CarFactory);
plane = UniversalVehicleFactory.getFactory().createVehicle(PlaneFactory);
Inside UniversalVehicleFactory I have the method createVehicle which is the method I'm having a problem with. What I'm trying to achieve is: take the parameter, determine its class and cast it to that, then call its internal createVehicle class.
public Vehicle createVehicle(AbstractFactory factory) {
// I want to take factory,
// cast it to the concrete factory, and
// call createMethod() on the factory
return factory.getInstance().createVehicle();
}
Help with this problem much appreciated!
I'll answer your question, but I'm curious why you want a universal factory to call a method of an abstract factory, if indeed you have to supply an instance of that factory as a parameter; you would be better off just invoking the creation method of the abstract factory directly.
Generics were invented for this purpose.
interface Factory< T > {
T make();
}
public class CarFactory implements Factory< Car > {
Car make() { ... }
}
public class PlaneFactory implements Factory< Plane > {
Plane make() { ... }
}
public class UniversalVehicleFactory {
public < T extends Vehicle > T make( Factory< T > factory ) {
return factory.make();
}
}
You'll notice that UniversalVehicleFactory doesn't implement Factory< T >.
I think you are trying to apply Abstract Factory pattern here. Here are my solution:
You can have interface VehicleFactory and factory classes:
interface VehicleFactory {
Vehicle createVehicle();
}
class CarFactory implements VehicleFactory {
public Vehicle createVehicle() {
return new Car();
}
}
class PlaneFactory implements VehicleFactory {
public Vehicle createVehicle() {
return new Plane();
}
}
Then if you want to centralize all the factory, you can have a UniversalVehicleFactory:
class UniversalVehicleFactory {
private Map<Class<T extends VehicleFactory>, VehicleFactory> factories;
static {
factories = new HashMap<Class<T extends VehicleFactory>, VehicleFactory>();
factories.put(CarFactory.class, new CarFactory());
factories.put(PlaneFactory.class, new PlaneFactory());
}
public static VehicleFactory getFactory(Class<T extends VehicleFactory> factoryClass) {
return factories.get(factoryClass);
}
}
Then in your code, use can use it like this:
Vehicle car = UniversalVehicleFactory.getFactory(CarFactory.class).createVehicle();
Vehicle plane = UniversalVehicleFactory.getFactory(PlaneFactory.class).createVehicle();
Here is some generalized code that might help you out:
public class A
{
public void paint(Graphics g)
{
}
}
public class B extends A
{
public static void main(String args[])
{
A a = new A();
B b = new B();
// This is the only one that won't work, because a is not an instance of b.
if(a instanceof B)
((B)a).draw(new Graphics());
if(b instanceof B)
((B)b).draw(new Graphcis());
if(a instanceof A)
((A)a).paint(new Graphics());
if(b instanceof A)
((A)b).paint(new Graphics());
}
public void draw(Graphics g)
{
}
}
instanceof is a great tool to use before typecasting to avoid errors. I hope this helped, if it was too general and you want me to apply it more to your situation let me know.
Related
I want to create a new instance depending on an object, where I have the super class variable. Is this somehow possible without implementing a getNew() function or without usage of an ugly if chain?
In other words: How to implement the following newSubClass(..) function without using the getNew() function?
public abstract class SuperClass {
abstract public SuperClass getNew();
}
public class SubClassA extends SuperClass {
#Override
public SuperClass getNew() {
return new SubClassA();
}
}
public class SubClassB extends SuperClass {
#Override
public SuperClass getNew() {
return new SubClassB();
}
}
private SuperClass newSubClass(SuperClass superClass) {
return superClass.getNew();
}
After having some time to think about and zv3dh's contribution I decided this second answer.
I'am getting now you want an new instance of an instance of a subclass' type of SuperClass without knowing the concrete sub-type at runtime.
For that you have "reflexion".
public abstract class A_SuperClass {
public A_SuperClass createNewFromSubclassType(A_SuperClass toCreateNewFrom) {
A_SuperClass result = null;
if (toCreateNewFrom != null) {
result = toCreateNewFrom.getClass().newInstance();
}
// just an example, add try .. catch and further detailed checks
return result;
}
}
public class SubClassA extends A_SuperClass {
}
public class SubClassB extends A_SuperClass {
}
If you search for "java reflexion" you will get lots of results here on SO and on the web.
Have a look at the "FactoryMethod" design pattern.
It is exactly what you are looking for: It does encapsulate the "new" operator.
However your example makes me wonder:
Your getNew() reimplements what the constructor would do anyway
Try something like this:
public abstract class SuperClass {
public SuperClass createSuperClass(object someParam) {
if (someParem == a) return new SubClassA();
if (someParem == b) return new SubClassB();
}
}
public class SubClassA extends SuperClass {
}
public class SubClassB extends SuperClass {
}
As you see you need some IF at some place ...
I have a if statement, with multiple instanceof checks. Example:
if (object instanceof Object1) {
// do something
} else if (object instanceof Object2) {
// to something else
} else if (object instanceof Object2) {
// and something else
} ...
What would be a more elegant way to solve this if-else-query?
the best practice in OOP is to put the logic in the object itself and make it implement an interface:
the interface:
public interface MyLogic{
public void doLogic();
}
first object:
public class Object1 implements MyLogic{
public void doLogic(){// logic 1 here}
}
second object:
public class Object2 implements MyLogic{
public void doLogic(){// logic 2 here}
}
and now just move your logic to the objects itself and instead all the if statements just use
object.doLogic(); // make sure object is from type MyLogic, if not, cast it
This seems to be polymorphism so you can create an Interface and implement it for every Object.
interface ObjectToBeImplemented{
method();
}
class Object1 implements ObjectToBeImplemented{
#Override
method(){...}
}
class Object2 implements ObjectToBeImplemented{
#Override
method(){...}
}
class Object3 implements ObjectToBeImplemented{
#Override
method(){...}
}
This is a typical usage for interfaces. See interfaces as defining the Type of an instance. Therefore, you know that all instance of a certain Type can do a particular task. At that point, you don't really care about the concrete class of the object, you just know it has that particular interfaces available to you to use.
Example :
public interface Worker {
public void doWork();
}
public class Object1 implements Worker {
public void doWork() {
// work for this specific object
}
}
public class Object2 implements Worker {
public void doWork() {
// work for this specific object
}
}
public class Object3 implements Worker {
public void doWork() {
// work for this specific object
}
}
Then your if statements would be replaced by
obj.doWork();
This feels like a missed opportunity for polymorphism.
This is where a bunch of classes share the same method signatures as their superclass/interface, so the code that calls it doesn't need to know which type it is.
Without polymorphism:
Employee employee = ...;
if(employee instanceof Doctor) {
salary = calcDoctorSalary(...);
} else if(employee instanceof Nurse) {
salary = calcNurseSalary(...);
}
With polymorphism:
Employee employee = ...;
salary = employee.calcSalary(...);
The magic goes into the subclasses. calcSalary() is abstract in a superclass, or a method signature in an interface:
public abstract class Employee {
public abstract int calcSalary(...);
}
... or ...
public interface Employee {
public int calcSalary(...);
}
Then the type-dependent logic goes into the subclasses:
public class Nurse implements Employee {
#Override
public int calcSalary(...) {
// code specific to nurses goes here.
}
}
Whether to extend a class, or implement an interface, is something you'll learn with experience. Often when one doesn't start with an interface, one regrets it later.
I have the following setup:
class Base {};
class ImplA extends Base {};
class ImplB extends Base {};
class ImplC extends Base {};
Base baseFactory(int type) {
switch(type) {
case 0:
return new ImplA();
case 1:
return new ImplB();
case 2:
return new ImplC();
}
Base a = baseFactory(0);
Base b = baseFactory(1);
Base c = baseFactory(2);
List<Base> list = new ArrayList<Base>();
list.add(a);
list.add(b);
list.add(c);
// Somewhere else I have:
interface BaseHandler {
process(ImplA a);
process(ImplB b);
process(ImplC c);
};
Now, what I would like to be able to do is something along the lines of:
class Processor {
BaseHandler bh;
Processor(BaseHandler bh) {
this.bh = b;
}
void processList(List<Base> list) {
for (Base x : list) {
bh.process(x);
}
}
And then have a user implement BaseHandler and be able to construct a Processor to operate on each element in the Base list.
But, this does not work as process(Base) is not defined. It may seem simple to just add 3 if statements, but I already have a switch like structure in building instances of classes extending the Base. It seems unnecessary to repeat this over and over. Is there a way to achieve this idea without writing an intermediate step that determines the runtime class of each Base in the list and calls the appropriate method (in effect another switch case -- but it would be if's)?
I think one work around idea would be to make each Base have an abstract process method which needs to be implemented by the Impl classes. However, this is not acceptable in my situation since the user will not be implementing the Impl classes. Basically, I need process to be a user-defined callback. Further, it does not make sense for process to be a member of the Impl or Base classes since it is in no way related. It's a separate callback that needs to respond dynamically to the type it is called with. And the type is always guaranteed to be a subclass of Base.
You do need the "intermediate step" that you describe, but it need not be if statements. What you're looking for is double dispatch using the visitor pattern. Basically your Base class would have a method:
void accept(BaseHandler handler);
and each subclass would implement it as:
handler.process(this);
where this would resolve to the correct type in each subclass at compile-time.
What you're looking for is the Visitor pattern. You put an abstract method on Base, but all it does is call the appropriate method in BaseHandler:
public interface Base {
void acceptHandler(BaseHandler handler);
}
Then your concrete implementations override acceptHandler and call the correct overload.
public class ImplA implements Base {
public void acceptHandler(BaseHandler handler) {
handler.process(this);
}
}
At this point there's not much value in the overloading, and you'd be better off just giving your methods descriptive names.
It sounds like what you want is the Visitor pattern here:
public interface BaseVisitor {
void caseA(ImplA a);
void caseB(ImplB b);
void caseC(ImplC c);
}
public class MyVisitor implements BaseVisitor {
void visit(List<Base> bases) {
for (Base b : bases) {
b.accept(this);
}
}
public void caseA(ImplA a) { // ... }
public void caseB(ImplB b) { // ... }
public void caseC(ImplC c) { // ... }
}
public abstract class Base {
abstract void accept(BaseVisitor visitor);
}
public class ImplA {
public void accept(BaseVisitor visitor) {
visitor.caseA(this);
}
}
public class ImplB {
public void accept(BaseVisitor visitor) {
visitor.caseB(this);
}
}
public class ImplC {
public void accept(BaseVisitor visitor) {
visitor.caseC(this);
}
}
Ok, maybe this is a stupid question. But i'm just wondering if this can be done in java.
abstract public class ParentClass<T> {
abstract public T getTest();
}
in the subclass
public class SubClass extends ParentClass<MyObject> {
public MyObject getTest() {
// I can return the object with class MyObject
return null;
}
}
My question is can I return the class type in the child method? I mean, is it can be done by adding some code in the ParentClass, so I can do this below?
For example
public class Sub1Class extends parentClass<Object1> {
public Object1 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub1Class getItClassObject() { }
}
other example
public class Sub2Class extends parentClass<Object2> {
public Object2 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub2Class getItClassObject() { }
}
one example again
public class Sub3Class extends parentClass<Object3> {
public Object3 getTest() { }
// I want to have a method that return it's class in the superclass
public Sub3Class getItClassObject() { }
}
if you see, method getItClassObject in Sub1Class, Sub2Class and Sub3Class will follow it's class. But I don't want to add same method for every subclass, just want to add some code (if feasible) in the ParentClasss, so in the subclass, I just can call getItClassObject directly without write all the code in every subclass.
Usually I add method in ParentClass like this.
abstract public class ParentClass<T> {
abstract public T getTest();
public Object getItClassObject() { }
}
so in the subclass I just instance the class, but I have to cast again :(
Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = (Sub1Class) sub1Class.getItClassObject();
Sub2Class sub2Class = new Sub2Class();
Sub2Class after2Cast = (Sub2Class) sub2Class.getItClassObject();
I think it cannot be done in java. But I don't know if there is a clue to solve this. Thanks
This is what you want I think. The following compiles:
abstract class A {
public abstract A getA();
}
class B extends A {
// Declared to return a B, but it still properly overrides A's method
#Override
public B getA() {
return new B();
}
}
class C extends A {
// Declared to return a B, but it still properly overrides A's method
#Override
public C getA() {
return new C();
}
}
As you can see, A declares that the getA() method returns an A. But, you can restrict the return type in subclasses as shown.
I'm not sure if I understand your intent correctly, but I think the built-in Object.getClass() method will do what you want. Given classes defined as:
public abstract class ParentClass<T> {
public abstract T getTest();
}
class SubClassString extends ParentClass<String> {
public String getTest() {
return "";
}
}
class SubClassInteger extends ParentClass<Integer> {
public Integer getTest() {
return Integer.valueOf(0);
}
}
getClass() will return the correct run-time class
public static void main(String[] args) {
SubClassString subString = new SubClassString();
// displays "class SubClassString"
System.out.println(subString.getClass());
SubClassInteger subInteger = new SubClassInteger();
// displays "class SubClassInteger"
System.out.println(subInteger.getClass());
ParentClass<?> parentInstance = new SubClassInteger();
// displays "class SubClassInteger"
System.out.println(parentInstance.getClass());
}
The only way I can think of is by telling the parent class what the subclass is when you extend it (just like you did with 'T'). Eg:
public abstract class ParentClass<T,U> {
abstract public T getTest();
abstract public U getItClassObject();
}
They you define your subclass like so:
public class Sub1Class extends ParentClass<Object1,Sub1Class> {
public Object1 getTest() { }
public Sub1Class getItClassObject() { }
}
Then you can do what you want without the typecast:
Sub1Class sub1Class = new Sub1Class();
Sub1Class after1Cast = sub1Class.getItClassObject();
If your objects have no-arg constructors (or some consistent form of constructor across all of them), you can use reflection to do it. Some pseudocode would be
public class MyClass {
public MyClass instantiateType() {
Class<?> actualClass = getClass();
return actualClass.newInstance();
}
}
This is using the runtime type of the class, so subclasses will return their type. This works only for a no-arg constructor though.
I'm looking to create a set of functions which all implementations of a certain Interface can be extended to use. My question is whether there's a way to do this without using a proxy or manually extending each implementation of the interface?
My initial idea was to see if it was possible to use generics; using a parameterized type as the super type of my implementation...
public class NewFunctionality<T extends OldFunctionality> extends T {
//...
}
...but this is illegal. I don't exactly know why this is illegal, but it does sort of feel right that it is (probably because T could itself be an interface rather than an implementation).
Are there any other ways to achieve what I'm trying to do?
EDIT One example of something I might want to do is to extend java.util.List... Using my dodgy, illegal syntax:
public class FilterByType<T extends List> extends T {
public void retainAll(Class<?> c) {
//..
}
public void removeAll(Class<?> c) {
//..
}
}
You can achieve something like this using a programming pattern known as a 'decorator' (although if the interface is large then unfortunately this is a bit verbose to implement in Java because you need to write single-line implementations of every method in the interface):
public class FilterByType<T> implements List<T> {
private List<T> _list;
public FilterByType(List<T> list) {
this._list = list;
}
public void retainAll(Class<?> c) {
//..
}
public void removeAll(Class<?> c) {
//..
}
// Implement List<T> interface:
public boolean add(T element) {
return _list.add(element);
}
public void add(int index, T element) {
_list.add(index, element);
}
// etc...
}
Alternatively, if the methods don't need to access protected members, then static helper methods are a less clucky alternative:
public class FilterUtils {
public static void retainAll(List<T> list, Class<?> c) {
//..
}
public static void removeAll(List<T> list, Class<?> c) {
//..
}
}
What prevents you from just adding new methods to the interface?
If you can't just add the new functionality to old interface, you could consider making another interface and then an implementation which merely implements those two. Just to be clear, in code this is what I mean:
// Old functionality:
public interface Traveling {
void walk();
}
// Old implementation:
public class Person implements Traveling {
void walk() { System.out.println("I'm walking!"); }
}
// New functionality:
public interface FastTraveling {
void run();
void fly();
}
// New implementation, option #1:
public class SuperHero extends Person implements FastTraveling {
void run() { System.out.println("Zoooom!"); }
void fly() { System.out.println("To the skies!"); }
}
// New implementation, option #2:
public class SuperHero implements Traveling, FastTraveling {
void walk() { System.out.println("I'm walking!"); }
void run() { System.out.println("Zoooom!"); }
void fly() { System.out.println("To the skies!"); }
}
I think it's illegal because you can not guarantee what class T will be. Also there are technical obstacles (parent's class name must be written in bytecode, but Generics information get lost in bytecode).
You can use Decorator pattern like this:
class ListDecorator implements List {
private List decoratingList;
public ListDecorator(List decoratingList){
this.decoratingList = decoratingList;
}
public add(){
decoratingList.add();
}
...
}
class FilterByArrayList extends ListDecorator {
public FilterByAbstractList () {
super(new ArrayList());
}
}
There is a delegation/mixin framework that allows a form of this. You can define a new interface, implement a default implementation of that interface, then request classes which implement that interface but subclass from elsewhere in your hierarchy.
It's called mixins for Java, and there's a webcast right there that demonstrates it.
I'm afraid it's not clear what do you want to get.
Basically, I don't see any benefit in using 'public class NewFunctionality<T extends OldFunctionality> extends T' in comparison with 'public class NewFunctionality extends OldFunctionality' ('public class FilterByType<T extends List> extends T' vs 'public class FilterByType<T> implements List<T>')