Object data with 2 different types - java

I have the following:
public class Notifier{
CustomPlayer mCustomPlayer;
CurrentPlayer mCurrentPlayer;
}
public class MainActivity extends Activity{
public void onCreate(){
Notifier ntf = new Notifier();
if( index == 0){
ntf.mCustomPlayer = new CustomPlayer(this);
}
else{
ntf.mCustomPlayer = new CurrentPlayer(this); // having problem here
}
}
}
In Notifier class, I just want to have one object mCustomPlayer to switch between CustomPlayer and CurrentPlayer in MainActivity class.
I tried adding the following in Notifier class,
public class Notifier{
CustomPlayer mCustomPlayer;
CurrentPlayer mCurrentPlayer;
public Object getType(int index) {
if (index == 1) {
return CurrentPlayer.class;
}
else {
return CustomPlayer.class;
}
}
}
With that I am having a problem when trying to initialize mCustomPlayer in MainActivity class.
ntf.mCustomPlayer = new (ntf.mCustomPlayer)getType(0); // compile error
Is there a way to realize this?
It has been a day since I am trying to configure out the correct implementation.
Should I use Interface in this case?

To use the new keyword you must supply a class (i.e. new MyClass()).
You could use reflection for this... but wouldn't it be much simpler to just have a common superclass (or interface) for CustomPlayer and CurrentPlayer?
For example, suppose both CustomPlayer and CurrentPlayer have the playOne() and playTwo() methods. You could then define:
public interface Player {
void playOne();
void playTwo();
}
public class CurrentPlayer implements Player {
#Override
public void playOne() {
// code
}
#Override
public void playTwo() {
// code
}
}
private class CustomPlayer implements Player {
#Override
public void playOne() {
// code
}
#Override
public void playTwo() {
// code
}
}
public class Notifier {
Player mPlayer;
}
And then assign mPlayer with new CurrentPlayer() or new CustomPlayer() You can then call any methods on the interface.

You could using Reflection:
public class Notifier{
public CommonInterface getInstance(int index, Class<Activity> activity){
Class<?> claz = getType(0);
Constructor<?> cons = claz.getConstructor(activity);
return (CommonInterface) cons.newInstance(this);
//or you could just type cast it manually if you do not wish to use CommonInterface
}
But having a common interface is the right way to go. You dont have to worry about reflection then.

Since you have same function for both the classes so use interface and access the object -
public class MainActivity extends Activity{
interface CurrentPlayer { void game(); }
interface CustomPlayer { void game(); }
interface Player extends CurrentPlayer, CustomPlayer { }
public void onCreate(){
Player swan = new Player() {
#Override
public void game() {
System.out.println("Swan Player"); //Swan Player
}
};
}
}

Related

How call subclass method by superclass object

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.

Abstract method with different parameters Java

public abstract class CommonClass {
abstract void send(<what should i put here???>) {}
}
public class ClassA extends CommonClass {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass {
void send(List<Post> postList) {
// do stuff
}
}
I am new to OODP, I am trying to have a method that is able to take in any kind of List data so that I can abstract things out. How can i do this?
You could make it generic on some type T. Like,
public abstract class CommonClass<T> {
abstract void send(List<T> al);
}
And then, to implement it - use the generic. Like,
public class ClassA extends CommonClass<Comments> {
#Override
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
Also, as discussed in the comments, your class names could be improved to be more intuitive; something like,
public abstract class AbstractSender<T> {
abstract void send(List<T> al);
}
and then
public class CommentSender extends AbstractSender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender extends AbstractSender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
That has the advantage(s) of being more readable and easier to reason about (I can tell what a PostSender does by reading the name, ClassB not so much).
Finally, this looks like a case where an interface would work since your abstract class is purely virtual (and should be preferred since you can implement multiple interface, but can only extend from a single parent class);
public interface ISender<T> {
void send(List<T> al);
}
public class CommentSender implements ISender<Comment> {
#Override
void send(List<Comment> commentsList) {
// do stuff
}
}
public class PostSender implements ISender<Post> {
#Override
void send(List<Post> postList) {
// do stuff
}
}
In order to achieve this, you can take multiple approaches, I would suggest looking into Generics: https://docs.oracle.com/javase/tutorial/java/generics/index.html
With that said, there is one approach that is the most elegant and simple: you can supply a List<T> where T is a generic type.
public abstract class CommonClass<T> {
abstract void send(List<T>) {}
}
public class ClassA extends CommonClass<Comment> {
void send(List<Comments> commentsList) {
// do stuff
}
}
public class ClassB extends CommonClass<Post> {
void send(List<Post> postList) {
// do stuff
}
}
You can do that with the help of generics. https://www.tutorialspoint.com/java/java_generics.htm
Example
The abstract class
public abstract class CommonClass {
public abstract <T> void send(List<T> data);
}
Its child
public class Child extends CommonClass {
public <T> void send(List<T> data) {
// code here
}
}
Retrieving the list's contents
Retrieving the generified list's contents is similar to retrieving any list's contents. In the scope of the method, "T" is a type of object contained in the list.
for (T t : data) {
// to check if t is a string
if (t instanceof String) {
// code
}
}
You can also use lambdas to retrieve every element in the list.

GameObjects and Code Structure

I have the following GameObject interface:
public interface GameObject {
void viewDetails();
}
Character Interface:
interface Character{
void pickUp(Weapon weapon);
void use(Weapon weapon);
}
and abstract Weapon class:
public abstract class Weapon implements GameObject {
//left out constructor to focus on methods
#Override
public abstract void viewDetails();
public abstract void attack(Enemy enemyObj);
//Could be bullets, could be a mystical item.
public abstract void replenish(ReplenishItem rpItem);
}
The problem with this is, a GameObject sometimes can be used in different ways.
For example, the primary use of a game weapon is to attack a target, but what if I wanted to reload? How do I let my character interface reload or beware that reload is an option?
I would use the following approach.
I would declare interfaces:
interface MeleeWeapon {
void hit();
void cut();
}
interface FirearmWeapon {
void fire();
void reload();
}
interface MagicWeapon {
void throw();
void apply();
void recharge();
}
Then implement classes, like these:
class Knife implements MeleeWeapon {
public void hit() {
}
public void cut() {
}
}
class Dagger implements MeleeWeapon {
public void hit() {
}
public void cut() {
}
}
class GarandRifle implements FirearmWeapon {
public void fire() {
}
public void reload() {
}
}
class Fireball implements MagicWeapon {
public void throw() {
}
public void apply() {
}
public void recharge() {
}
}
Then, I would declare these interfaces:
interface MeleeWeaponUser {
void use(MeleeWeapon weapon);
}
interface FirearmWeaponUser {
void use(FirearmWeapon weapon);
}
interface MagicWeaponUser {
void use(MagicWeapon weapon);
}
And, I would declare character classes:
class Peasant implements MeleeWeaponUser {
public void use(MeleeWeapon weapon) {
}
}
class Marine implements MeleeWeaponUser, FirearmWeaponUser {
public void use(FirearmWeapon weapon) {
}
public void use(MeleeWeapon weapon) {
}
}
class Sorcerer implements MeleeWeaponUser, MagicWeaponUser {
public void use(MeleeWeapon weapon) {
}
public void use(MagicWeapon weapon) {
}
}
This approach let us add new weapons and characters without sufficient effort later.
In your use() method you can call reload() if there is no more ammo in the weapon dispenser.
But if your game character receives signal from outside, for example, reload the gun, even there is enough ammo to fire, then have an Event->Listener approach implemented.
Create a WeaponEvent class, extend this class to have FirearmWeaponEvent, MeleeWeaponEvent etc.
Make your game character class(es) as a listener to WeaponEvent events, then in your game character class have a method processEvent(WeaponEvent event), and act accordingly to the event you have received.

Passing parameter to anonymous class in Java

i'm trying to write anonymous inner class
interface Face{
void seeThis(String what);
}
class Eyes {
public void show(Face f){}
}
public class Seen {
public void test() {
Eyes e = new Eyes();
e.show(new Face() {
#Override
public void seeThis(String what){
System.out.print(what);
}
});
public static void main(String[] args) {
Seen s = new Seen();
s.test();
}
}
How to call seeThis() and how to pass parameter to it?
Method seeThis() belongs to Face class, which instance is anonymous and thus cannot be reached without storing reference to it. If you want to store a reference, you can do this in the following way:
public class Seen {
public Face face;
....
this.face = new Face() { ... };
e.show(this.face);
And then,
Seen s = new Seen();
s.face.seeThis();
Now, regarding passing the parameter. You have two options - declare parameter outside of anonymous class and make it final in order to be reachable by this anonymous class, or replace anonymous class with normal one and pass the parameter to its constructor:
Approach one:
final int parameter = 5;
...(new Face() {
#Override
public void seeThis() {
System.out.println(parameter);
}
});
Approach two:
public class MyFace implements Face() {
private final int parameter;
public MyFace(int parameter) {
this.parameter = parameter;
}
#Override
public void seeThis() {
System.out.println(parameter);
}
}
Then,
...
e.show(new MyFace(10));

using object functions in java

I'm trying to implement function objects in Java. I have a Unit class, with a default addition function that should be used in most initializations of a Unit object. However, for some issues, I need a different addition function. The code will look something like this:
public class Unit() {
public Unit(unitType) {
if (unitType == "specialType") {
additionFunc = defaultFunc } else {
additionFunc = specialFunc }
}
}
public int swim() {
return additionFunc()
}
// definiion of regularFunc
// definition of specialFunc
}
Then, from the main file:
Unit fish = new Unit(regularTyoe);
Unit fatFish = new Unit(specialType);
fish.swim(); //regular function is called
fatFish.swim(); //special function is called
That's it.. does anyone know how this can be done?
You need to look up inheritance and method overriding. It would probably help to read up on proper Object Oriented Programming as well.
The proper way to do this is:
class Fish {
public void swim() {
// normal swim
}
}
class FatFish extends Fish {
#Override
public void swim() {
// special swim
}
}
Fish fish = new Fish()
Fish fatFish = new FatFish()
fish.swim() // normal swim
fatFish.swim() // slow swim
Make a new FatFish class which extends Unit and overrides swim().
Unit fish = new Unit();
Unit fatFish = new FatFish();
fish.swim(); //regular function is called
fatFish.swim(); //special function is called
There are many solutions for your problem, one of them is using inheritance, that you could have a default implementation of Unit, and extend it overriding the desired method with a new one.
Basically would be something like:
public class FatFish {
#Override
public void swim() {
// new behavior
}
}
Another approach would be to implement Strategy Design Pattern, which allows you to select algorithms on runtime. Therefore you could do something like:
public interface SwimStrategy {
void execute();
}
public class FatFishSwimStrategy implements SwimStrategy {
#Override
public void execute() {
// fat fish swim impl
}
}
public class FishSwimStrategy implements SwimStrategy {
#Override
public void execute() {
// normal fish swim impl
}
}
public class Fish {
private final SwimStrategy swimStrategy;
public Fish(SwimStrategy swimStrategy) {
this.swimStrategy = swimStrategy;
}
public void swim() {
swimStrategy.execute();
}
}
In order to instantiate an object you could do:
new Fish(new FatFishSwimStrategy());
or for the normal behavior:
new Fish(new FishSwimStrategy());
I think it can do by extends and factory method:
public class Unit {
public static Unit createUnit(UnitType type) {
if (UnitType.Special == type) {
return new Unit(type) {
#Override
public int swim() {
System.out.println("special swim");
return 0;
}
};
}
return new Unit(UnitType.Default);
}
private UnitType type;
private Unit(UnitType type) {
this.type = type;
System.out.println("create unit for " + type);
}
public int swim() {
System.out.println("default swim");
return 0;
}
public static void main(String[] args) {
Unit fish = Unit.createUnit(UnitType.Default);
Unit fatFish = Unit.createUnit(UnitType.Special);
fish.swim();
fatFish.swim();
}
}
This is a simple type enum:
public enum UnitType {
Default, Special
}
There are two ways to accomplish this polymorphic behavior in Java. The first is to use a inheritance and a hierarchical set of classes. For example, you could have an abstract base class which defines an abstract method called "swim". Then each concrete fish class would extend this base class and implement the swim method. Later when you have a set of fish objects, you can upcast them to the base class and invoke the swim method on each.
The second way is to use interfaces. You define an interface (e.g. ISwim) which declares the public method swim. Each fish class (whether part of a class hierarchy or no) would implement the ISwim interface, meaning they would define a swim method. Then if you have a set of fish class objects of different types, you can cast each to the ISwim interface and invoke the swim method on each object.
Java does not have function pointers, so the approach you are considering is inappropriate for the language. Even in languages with function pointers, the above two approaches would be most appropriate in my opinion.
One way to do this is with an enum for the types of Unit and with Unit subclasses:
public class Unit {
public enum UnitType {
REGULAR {
public Unit makeUnit() {
return new RegularUnit();
}
},
SPECIAL {
public Unit makeUnit() {
return new SpecialUnit();
}
};
abstract public Unit makeUnit();
}
protected Unit() {}
public abstract int swim();
private static class RegularUnit extends Unit {
RegularUnit() {}
public int swim() {
return 0;
}
}
private static class SpecialUnit extends Unit {
SpecialUnit() {}
public int swim() {
return 1;
}
}
}
Unit fish = UnitType.REGULAR.makeUnit();
Unit fatFish = UnitType.SPECIAL.makeUnit();
Another way is with Callable objects:
public class Unit {
public enum UnitType { REGULAR, SPECIAL }
private Callable<Integer> additionFunc;
public Unit(UnitType type) {
switch (type) {
case REGULAR:
additionFunc = new Callable<Integer>() {
public Integer call() {
return 0;
}
};
break;
case SPECIAL:
additionFunc = new Callable<Integer>() {
public Integer call() {
return 1;
}
};
break;
}
}
public int swim() {
return additionFunc();
}
}
Using a simple if statement:
private String unitType;
public Unit(unitType) {
this.unitType = unitType;
}
public int swim() {
if (unitType.equals("specialType") {
return specialFunc();
}
else {
return regularFunc();
}
}
Or using polymorphism and a factory method :
public abstract class Unit() {
protected Unit() {
}
protected abstract int addition();
public int swim() {
return addition();
}
public static Unit forType(String unitType) {
if (unitType.equals("specialType") {
return new SpecialUnit();
}
else {
return new RegularUnit();
}
}
private static class SpecialUnit extends Unit {
#Override
protected addition() {
// special addition
}
}
private static class RegularUnit extends Unit {
#Override
protected addition() {
// regular addition
}
}
}
Or using an Adder functional interface, defining an addition() method, and two concrete implementations of this interface:
private Adder adder;
public Unit(unitType) {
if (unitType.equals("specialType") {
this.adder = new SpecialAdder();
}
else {
this.adder = new RegularAdder();
}
}
public int swim() {
return adder.addition();
}
This last one is the closest to waht you asked in your question. function objects don't exist per se, but can be replaced by interfaces.

Categories

Resources