I'm using the Java instanceof but it doesn't seem to be working.
I have three java classes that extend a Hero class.
The Hero.java class:
public abstract class Hero {
protected int health;
public Hero() {
}
}
The other three classes:
public class Archer extends Hero {
public Archer() {
}
}
public class Mage extends Hero {
public Mage() {
}
}
public class Warrior extends Hero {
public Warrior() {
}
}
I have this main class WelcomeScreen.java
public class WelcomeScreen {
private Archer archer;
private Mage mage;
private Warrior warrior;
private Hero hero;
public WelcomeScreen() {
// choose a hero (archer/mage/warrior)
hero = archer;
new Game(hero);
}
public static void main(String args[]) {
new WelcomeScreen();
}
}
that instantiates the Game.java class
public class Game {
public Game(Hero chosenHero) {
if (chosenHero instanceof Mage) {
System.out.println("you selected mage");
} else if (chosenHero instanceof Archer) {
System.out.println("you selected archer");
} else if (chosenHero instanceof Warrior) {
System.out.println("you selected warrior");
} else {
System.out.println("you selected NOTHING");
}
}
}
In Game.java, the code is meant to check whether chosenHero is an object of Archer.java, Warrior.java, or Mage.java, but I result with "you selected NOTHING". Why does instanceof fail to check if I already assigned it to Archer.java in the WelcomeScreen?
Because your constants are null. When you say,
private Archer archer;
it is equivalent to
private Archer archer = null;
Additionally, you have created three fields per instance. I think you wanted to do something like
private static final Hero archer = new Archer();
private static final Hero mage = new Mage();
private static final Hero warrior = new Warrior();
See also What does it mean to “program to an interface”?
Alternative solution: get rid of instanceof as it suggests a brittle rigid design, one that's easily broken. Instead try to use other more OOP-compliant solutions such as inheritance, or if complex, a Visitor Design Pattern.
For example, a simple inheritance structure could look something like:
public class WelcomeScreen {
public WelcomeScreen() {
// choose a hero (archer/mage/warrior)
Hero hero = new Archer();
new Game(hero);
}
public static void main(String args[]) {
new WelcomeScreen();
}
}
abstract class Hero {
protected int health;
// other shared fields such as String name,...
public Hero() {
}
public abstract String getType();
public int getHealth() {
return health;
}
}
class Archer extends Hero {
public static final String TYPE = "Archer";
public Archer() {
}
#Override
public String getType() {
return TYPE;
}
}
class Mage extends Hero {
public static final String TYPE = "Mage";
public Mage() {
}
#Override
public String getType() {
return TYPE;
}
}
class Warrior extends Hero {
public static final String TYPE = "Warrier";
public Warrior() {
}
#Override
public String getType() {
return TYPE;
}
}
class Game {
private Hero hero;
public Game(Hero chosenHero) {
this.hero = chosenHero;
System.out.println("You selected a hero of type " + hero.getType());
}
}
Related
I have a program that can print a pizza with decorators. I have an interface:
public interface PizzaPie{
String top();
}
And an implementation of the interface
public class PizzaPieImplementation implements PizzaPie{
#Override
public String top() {
return "Pie of pizza";
}
}
And an abstract class that implements it with the same object.
public abstract class PizzaTopper implements PizzaPie{
private PizzaPie pizza;
#Override
public String top() {
return pizza.top();
}
}
And I have several decorator classes, such as
public class Onions extends PizzaTopper{
public Onions(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with onions";
}
And similar classes for peppers, pepperoni, anchovies, pineapple, etc.
I have a list as follows:
List<String> toppings = {onions, pineapple};
Is there a way to take each topping from the toppings list, and use that to create a new pizza with those toppings, to return something like:
Pie of pizza with onions with pineapple
The method would look something like this:
public PizzaPie CreatePizzaWithUserInput(List<String> toppings) {
//code
}
And ultimately it would create code that looks like this:
PizzaPie pizza1 = new Onion(new Pineapple(new PizzaPieImplementation()));
In theory this can be done with a lot of ugly if statements but I'm wondering if there's a quicker way of doing it.
You can use Java Reflection to achieve this.
Here we build our factory with the different possibilities of toppings, then we create a Pizza using createPizzaWithUserInput.
In this example we built a pizza with 3 of the four possible toppings.
Notice that to add a new Topping possibility you just extends PizzaTopper and add it on the toppingOptions on the PizzaFactory instantiation.
import java.util.List;
import java.util.LinkedList;
class Main {
public static void main(String[] args) {
// Possibilities
PizzaFactory pizzaFactory = new PizzaFactory(Onions.class, Bacon.class, Olives.class, Tomatos.class);
// User input
List<String> toppings = new LinkedList<String>();
toppings.add("onions");
toppings.add("olives");
toppings.add("bacon");
try{
PizzaPie pizza = pizzaFactory.createPizzaWithUserInput(toppings);
System.out.println(pizza.top());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here we have the PizzaFactory. We use the class' name to do the matching with the topping option, but you can customize it if you want (to match also "onion"/"onions" or "tomato"/"tomatos" for instance).
import java.util.List;
import java.util.Arrays;
import java.lang.reflect.*;
public class PizzaFactory {
List<Class<? extends PizzaTopper>> toppingOptions;
public PizzaFactory(Class<? extends PizzaTopper>... toppingOptions) {
this.toppingOptions = Arrays.asList(toppingOptions);
}
public PizzaPie createPizzaWithUserInput(List<String> toppings) throws NoSuchMethodException, InstantiationException, IllegalAccessException,InvocationTargetException {
PizzaPie pizza = new PizzaPieImplementation();
for(String toppingName : toppings) {
for(Class<? extends PizzaTopper> top : toppingOptions) {
if(top.getName().toLowerCase().equals(toppingName.toLowerCase())) {
Constructor<? extends PizzaPie> constructor = top.getConstructor(PizzaPie.class);
pizza = constructor.newInstance(pizza);
}
}
}
return pizza;
}
}
Here we have the interface PizzaPie:
public interface PizzaPie{
String top();
}
And its implementation.
public class PizzaPieImplementation implements PizzaPie{
#Override
public String top() {
return "Pie of pizza";
}
}
The decorator class.
public abstract class PizzaTopper implements PizzaPie{
private PizzaPie pizza;
protected PizzaTopper(PizzaPie pizza) {
this.pizza = pizza;
}
#Override
public String top() {
return pizza.top();
}
}
Tomatos topping.
public class Tomatos extends PizzaTopper{
public Tomatos(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with tomatos";
}
}
Onions topping.
public class Onions extends PizzaTopper{
public Onions(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with onions";
}
}
Olives topping
public class Olives extends PizzaTopper{
public Olives(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with olives";
}
}
Bacon topping.
public class Bacon extends PizzaTopper{
public Bacon(PizzaPie pizza) {
super(pizza);
}
public String top() {
return super.top() + topWithOnions();
}
private String topWithOnions() {
return " with bacon";
}
}
You could just make the member variable stored in PizzaTopper an array, and its constructor accept (PizzaPie... pizzas). Then, you could pass in an array of pizzas/toppings (anything implementing PizzaPie) and PizzaTopper.top() could return a runtime-generated concatenation of all of the PizzaPies' top() results.
I have 2 subclass extended from the same superclass, and 3 objects will be created and store into an array of the superclass. I am wondering how can I call a subclass method by a superclass object, I try to convert the data type from Ship to CruiseShip or CargoShip but it does not work. If anyone can help I will be appreciated that.
Here is the superclass:
public class Ship {
private String name;
private String year;
public Ship() {}
public Ship(String n,String y) {...}
public void setName() {...}
public void setYear() {...}
public void getName() {...}
public void getYear() {...}
}
These two subclass basically are there same.
public class CruiseShip extends Ship {
private int passenger;
public CruiseShip() {}
public CruiseShip() {...}
public void setPassenager() {...}
public int getPassenager() {...}
public Strting showInfo() {this.getName()...etc}
}
public class CargoShip extends Ship {
private int capacity;
public CargoShip() {}
public CargoShip() {...}
public void setCapacity() {...}
public int getCapacity() {...}
public Strting showInfo() {this.getName()...etc}
}
Here is the main method:
public class report {
public static void main(String[] args) {
Ship[] shipList new Ship[3];
for (int i=0;i<3;i++) {//using for loop to create 3 objects randomly and pass into array}
for (int i=0;i<3;i++) {
if (shipList[i] instanceof CruiseShip) {
((CruiseShip)shipList[i]).showInfo(); //This way is not work.
}
else {
((CargoShip)shipList[i]).showInfo(); //This way is not work.
}
Take a look at Polymorphisms and Late Bindig. Basically late binding says that the appropriate method to be executed is determined at runtime based on the actual type of the object. So
class Ship {
public String showInfo() {return "I'm a ship";}
}
class CruiseShip extends Ship {
public String showInfo() {return "I'm a cruiseShip";}
}
class CargoShip extends Ship {
public String showInfo() {return "I'm a cargoShip";}
}
class Main {
public static void main(String argv[]) {
Ship[] ships = new Ship[]{new Ship(), new CargoShip(), new CruiseShip()};
for (Ship ship: ships) {
System.out.println(ship.showInfo());
// I'm a ship
// I'm a cargoShip
// I'm a cruiseShip
}
}
}
I'm not sure about the question you are trying to ask,
but this may answer the question you did ask.
public abstract class Ship
{
public final boolean hoot()
{
return implementHoot();
}
protected abstract boolean implementHoot();
}
public class BlamShip
extends Ship
{
protected boolean implementHoot()
{
return true;
}
}
Subclass methods (overrides) are automatically called even if the reference is of type super-class. You don't have to do anything.
I want to write a new class that extends another, and in the new class I want to define a variable with the same name as one in the parent. I can do this fine in Java since both are private but when I try to serialize the object with gson I get an error since there are two properties with the same name (even if the one inherited from the parent class is null and therefore should not be included in the json).
For example consider these classes:
public class Car {
private String color;
private Seat seat;
}
public class Seat {
private boolean isAdjustable;
}
and these classes:
public class FancyCar extends Car {
private FancySeat seat;
private boolean hasSpoiler;
}
public class Fancyseat extends Seat {
private boolean hasSeatWarmers;
}
with these classes I could create a new FancyCar with a seat that isAdjustable and hasSeatWarmers. But if I were to serialize with gson it would throw an exception as it tries to parse both the variables named seat even if the one inherited from Car is null.
Is there a better way to design these classes? Or a way to tell gson to ignore null fields altogether?
You can use #SerializedName(value = "fancySeat") Also, from Gson version.2.4 There is an option to alternate or have multiple name for serializedName when deserializing. No Need of CustomTypeadapter.
Gson Field Naming
Example for Multiple deserialization names
package com.test.practice;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
public class JsonSerializationExample {
public static void main(String[] args) {
// TODO Auto-generated method stub
Seat seatCar = new Seat();
seatCar.setAdjustable(true);
Fancyseat fancySeat = new Fancyseat();
fancySeat.setHasSeatWarmers(true);
fancySeat.setAdjustable(false);
Car car = new Car();
car.setColor("black");
car.setSeat(seatCar);
FancyCar fancyCar = new FancyCar();
fancyCar.setColor("white");
fancyCar.setSeat(fancySeat);
Gson gson = new Gson();
String jsonString = gson.toJson(fancyCar);
System.out.println("json :: "+jsonString);
}
}
class Car {
private String color;
private Seat seat;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Seat getSeat() {
return seat;
}
public void setSeat(Seat seat) {
this.seat = seat;
}
}
class Seat {
private boolean isAdjustable;
public boolean isAdjustable() {
return isAdjustable;
}
public void setAdjustable(boolean isAdjustable) {
this.isAdjustable = isAdjustable;
}
}
class FancyCar extends Car {
#SerializedName(value = "fancySeat")
private Fancyseat seat;
private boolean hasSpoiler;
public Fancyseat getSeat() {
return seat;
}
public void setSeat(Fancyseat seat) {
this.seat = seat;
}
public boolean isHasSpoiler() {
return hasSpoiler;
}
public void setHasSpoiler(boolean hasSpoiler) {
this.hasSpoiler = hasSpoiler;
}
}
class Fancyseat extends Seat {
private boolean hasSeatWarmers;
public boolean isHasSeatWarmers() {
return hasSeatWarmers;
}
public void setHasSeatWarmers(boolean hasSeatWarmers) {
this.hasSeatWarmers = hasSeatWarmers;
}
}
I came across a term called reflection. It is a feature commonly used in factory design patterns. I had a hard time understanding the concept because I’m still learning how to program. How can reflection be used in factory design patterns in C# or Java? Can anyone give me a simple example, and show me your code that uses reflection to implement factory design patterns?
Microsoft provides this code example of reflection, but i don't see how this can be used in factory design patterns.
// Using GetType to obtain type information:
int i = 42;
System.Type type = i.GetType();
System.Console.WriteLine(type);
The Output is: System.Int32
I would never use reflection to implement Factory design pattern, unless there was a special case. The below code is a terrible way to implement the factory design pattern. But since you wanted to know "How" to use reflection for factory design pattern here's the example:
namespace NaiveFactory
{
public interface Shape
{
void Draw();
}
public class Circle : Shape
{
public void Draw() { Console.WriteLine("Drawing Circle"); }
}
public class Rectangle : Shape
{
public void Draw() { Console.WriteLine("Drawing Rectangle"); }
}
public class ShapeFactory
{
public static Shape GetShape<T>() where T : Shape
{
return Activator.CreateInstance<T>();
}
public static Shape GetShape(string shapeName)
{
var assembly = Assembly.GetExecutingAssembly();
var type = assembly.GetType(shapeName).FullName;
return (Shape) Activator.CreateInstanceFrom(assembly.Location, type).Unwrap();
}
}
class Program
{
static void Main(string[] args)
{
var shape = ShapeFactory.GetShape<Circle>();
var shape2 = ShapeFactory.GetShape("NaiveFactory.Rectangle");
shape.Draw();
shape2.Draw();
Console.ReadKey();
}
}
}
EDIT
As per suggestion from #AlexeiLevenkov, I have added something close to Dependency injection and instantiating the Shape objects using Constructor Injection as well as with a method:
namespace NaiveFactory
{
public interface IBoard
{
void InternalDraw(string str);
}
public class ConsoleBoard : IBoard
{
public void InternalDraw(string str) { Console.WriteLine(str); }
}
public class DebugBoard : IBoard
{
public void InternalDraw(string str) { Debug.WriteLine(str); }
}
public interface Shape
{
IBoard Board { get; set; }
void Draw();
void SetBoard(IBoard board);
}
public class Circle : Shape
{
public IBoard Board { get; set; }
public Circle()
{
}
public Circle(IBoard board)
{
Board = board;
}
public void Draw() { Board.InternalDraw("Drawing Circle"); }
public void SetBoard(IBoard board)
{
Board = board;
}
}
public class Rectangle : Shape
{
public IBoard Board { get; set; }
public Rectangle()
{
}
public Rectangle(IBoard board)
{
Board = board;
}
public void Draw() { Board.InternalDraw("Drawing Rectangle"); }
public void SetBoard(IBoard board)
{
Board = board;
}
}
public class ShapeFactory
{
private static Dictionary<Type, Type> _configurationData = new Dictionary<Type, Type>();
public static Shape GetShape<T>() where T : Shape
{
return Activator.CreateInstance<T>();
}
public static void ConfigureContainer<T, U>()
{
_configurationData.Add(typeof(T), typeof(U));
}
public static Shape GetShape_UsingConstructorInjection(string shapeName)
{
var assembly = Assembly.GetExecutingAssembly();
var type = assembly.GetType(shapeName);
var constructor = type.GetConstructor(_configurationData.Keys.ToArray());
if (constructor != null)
{
var parameters = constructor.GetParameters();
return (from parameter in parameters where _configurationData.Keys.Contains(parameter.ParameterType)
select Activator.CreateInstance(_configurationData[parameter.ParameterType]) into boardObj
select (Shape) Activator.CreateInstance(type, boardObj)).FirstOrDefault();
}
return null;
}
public static Shape GetShape_UsingSetBoardMethod(string shapeName)
{
var assembly = Assembly.GetExecutingAssembly();
var type = assembly.GetType(shapeName);
var shapeObj = (Shape) Activator.CreateInstance(type);
if (shapeObj != null)
{
shapeObj.SetBoard((IBoard) Activator.CreateInstance(_configurationData[typeof (IBoard)]));
return shapeObj;
}
return null;
}
}
class Program
{
static void Main(string[] args)
{
ShapeFactory.ConfigureContainer<IBoard, ConsoleBoard>();
var shape = ShapeFactory.GetShape_UsingSetBoardMethod("NaiveFactory.Circle");
var shape2 = ShapeFactory.GetShape_UsingConstructorInjection("NaiveFactory.Rectangle");
shape.Draw();
shape2.Draw();
Console.ReadKey();
}
}
}
Java version for this question
Code:
public class TestReflectionFactoryDesign {
public static void main(String[] args) throws Exception {
Person student = PersonFactory.getPersonWithFullQualifiedClassName("com.test.reflectionFactoryDesign.Student");
student.say();
Person teacher = PersonFactory.getPersonWithClass(Teacher.class);
teacher.say();
Person student2 = PersonFactory.getPersonWithName("student");
student2.say();
}
}
class Student implements Person {
#Override
public void say() {
System.out.println("I am a student");
}
}
class Teacher implements Person {
#Override
public void say() {
System.out.println("I am a teacher");
}
}
interface Person {
void say();
}
class PersonFactory {
// reflection, by full qualified class name
public static Person getPersonWithFullQualifiedClassName(String personType) throws Exception {
Class<?> personClass = Class.forName(personType);
return getPersonWithClass(personClass);
}
// reflection, by passing class object
public static Person getPersonWithClass(Class personClass) throws Exception {
return (Person) personClass.newInstance();
}
// no reflection, the ordinary way
public static Person getPersonWithName(String personType) {
if (personType.equalsIgnoreCase("STUDENT")) {
return new Student();
} else if (personType.equalsIgnoreCase("TEACHER")) {
return new Teacher();
}
return null;
}
}
Output:
I am a student
I am a teacher
I am a student
I was trying to understand Decorator Pattern. Below is the code am trying to understand how it works.
public static void main(String[] args)
{
Room myRoom = new CurtainDecorator(new ColorDecorator(new SimpleRoom()));
System.out.println(myRoom.showRoom());
}
Below is my Concrete Class
public class SimpleRoom implements Room{
#Override
public String showRoom()
{
return "show room";
}
}
Below is my abstract Decorator class
public abstract class RoomDecorator implements Room{
public Room roomReference;
#Override
public String showRoom()
{
return roomReference.showRoom();
}
}
Below is my Decorator implementation1
public class ColorDecorator extends RoomDecorator{
#Override
public String showRoom()
{
return addColors(); //How does showRoom() method gets invoked here?
}
public ColorDecorator(Room room)
{
this.roomReference = room;
}
public String addColors()
{
return "Blue";
}
}
Below is my Decorator implementation 2
public class CurtainDecorator extends RoomDecorator{
public CurtainDecorator(Room room)
{
this.roomReference = room;
}
#Override
public String showRoom()
{
return this.roomReference.showRoom() + addCurtains(); //What will showRoom method invoke?
}
public String addCurtains()
{
return "Curtain";
}
}
Output is - BlueCurtain
My question are placed in the comment..
In the end you have:
CurtainDecorator(ref=ColorDecorator(ref=SimpleRoom)))
When you call showRoom from main, it calls the method of CurtainDecorator, which in turn first goes to it's reference (ColorDecorator in this case) that outputs 'Blue', then CurtainDecorator adds it's bit 'Curtain'.