0

I had a question on an interview where I had 2 types of foods, say bread and cake, was given the following:

 public class FoodFactory{};

 public class Food{};

 public static void main(String[] args) {
    Food foo = FoodFactory.get("bread");
    System.out.println(foo.getClass().getName());
 }

Given the FoodFactory class and Food class, I wasn't sure how to make this work so that it would print out "bread" for the class. It really seemed like the only way to have gotten it to print bread was to create a Bread class and have the FoodFactory return that.

I'm just wondering if I'm missing anything, because FoodFactory and Food were classes given so I assumed those were the only 2 classes I needed to change. Is there a way to have implemented the two classes given and made it print "bread" while using just those 2 classes?

6
  • Would be good to respect the Java syntax, especially for such a short snippet Commented May 7, 2016 at 19:34
  • 1
    "I had 2 types of foods, say bread and cake"--they should be two concrete classes extending Food I suppose. So the factory choose instance of which class to produce taking argument into account. Commented May 7, 2016 at 19:39
  • 1
    The short answer is no. If there's no class called Bread, then getClass().getName() is never going to print "Bread". Commented May 7, 2016 at 19:39
  • @Dici yea sorry, I was just typing it up real quick my bad. Ok that makes sense. I kept trying to think about how this could be done with the classes given and didn't think it would allow me to make subclasses. Mistakes. Thanks again! Commented May 7, 2016 at 19:40
  • @Kevin the crazy solution may be to use bytecode library like javassist to create classes in runtime, but I think this is not what interviewer waits to hear. Commented May 7, 2016 at 19:44

5 Answers 5

2

So one way to do it would be to make a class Bread which extends class Food and have the FoodFactory.get() return the appropriate object based on the string passed.

class Food {};

class Bread extends Food {};

class FoodFactory {
    public static Food get(String type){
        switch(type){
            case "bread" : return new Bread();
            default : return new Food();
        }     
    }
}

Another way to do it would be to use reflection.

Sign up to request clarification or add additional context in comments.

1 Comment

This has 3 classes. But as the question mentions, there were only two classes
0

Unless you compile a new class at runtime (which is possible, but inappropriate here), you will of course need to add a class if you want to return a Bread instance.

Comments

0

Ideally, Food should turn into an interface or an abstract class at best. Then you have classes Bread and Cake implement/extend Food. Your FoodFactory has a static method get that accepts the food as a String. Depending on the value, you instantiate and return one of the concrete classes which will give you what you need when you print class name.

Comments

0

I think that the real question the interviewer was asking was if you understand the pattern and polymorphism. As noted in one of the comments getClass().getName() won't return 'Bread' unless there really is a Bread class. What you could have done was to the suggest the interviewer that Food is the base class which in this case should be extended by Cake and Bread classes, or even propose to change it to abstract class or interface. Then you could have proposed a simple factory class which would create the required implementation 'hidden' behind the base class interface.

Comments

0

Your problem is basically an example for the Java Factory Design Pattern. Assumed you have a project, respectively a class hierarchy with multiple Interfaces and different classes, what would be the easiest way to create any class? This is where a Factory comes in place to handle all operations regarding class instance creation.

Now to your case, the convenient way would be to change your Class Food to an interface eg:

public interface Food {
    String getType();
}

Now you need your Cake and Bread classes, which implement the interface Food

public class Cake implements Food{
    @Override
    public String getType() {
        return "Cake";
    }
}

public class Bread implements Food{
    @Override
    public String getType() {
        return "Bread";
    }
}

Now you need to define your FoodFactory class which has a static getmethod, that returns a Food depending on the criteria that has been supplied.

public class FoodFactory {
    public static Food get(String classifier){
        if(classifier.equals("Cake")) return new Cake();
        if(classifier.equals("Bread")) return new Bread();
    //no matching Food to create    
    throw new IllegalArgumentException("The " + classifier + " is not a valid classifier");
    }
}

Once you have your Factory you can use it for any creation operation. If you want to print out Bread from a Food instance, you can achieve this like this:

//food is now an instanceof Bread
Food food = FoodFactory.get("Bread");
System.out.println(food.getType());

Which simply just prints

Bread

Further: To make sure every creation is handled only by the FoodFactory you should make every constructor of your Food classes protected

Comments

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.