Is it possible to run methodnameX depending on X value? - java

If there are 3 methods in
public class Hero extends GameCharacter {
public void test1(){};
public void test2(){};
public void test3(){};
is it possible while running this in
public class MainClass extends ApplicationAdapter implements InputProcessor {
#Override
public void create () {
private Hero mainHero;
For (int x = 0; x < 0; x++)
....
to run
mainhero.testx
?

This situation is suitable for Strategy Pattern. Basically you have a variation in functionality, so you create an interface for executing it, and create multiple implementations of it. It could look something like this:
package test;
public class Test {
public static interface TestStrategy {
void test();
}
public static class Test1 implements TestStrategy {
#Override
public void test() {
System.out.println("1");
}
}
public static class Hero {
TestStrategy test[] = new TestStrategy[]{
//either use defined class
new Test1(),
//or inline
() -> {System.out.println("2");}
};
}
public static void main(String[] args) {
Hero hero = new Hero();
for (int i = 0; i < hero.test.length; i++) {
hero.test[i].test();
}
}
}

You could using reflection, but you should evaluate better patterns for this.
Alternative solutions include
Conditionals
public void test(int x){
switch (x) {
case 1:
// Things for x == 1
break;
}
};
OOP, for when you have different types of Heroes
public abstract class Hero extends GameCharacter {
public abstract void test();
}
public class Hero1 extends Hero {
#Override
public void test() {}
}
...
List<Hero> heroes = ... ;
heroes.add(new Hero1());
for (Hero h : heroes) { h.test(); }
Or, just call all your test methods separately via independent unit-testing methods.

Like suggested before, you could use reflection for this. This example uses reflection to demonstrate that.
public void callYourClassMethod(String x) {
try {
YourClass yourClass = new YourClass()
Method method = YourClass.class.getDeclaredMethods("methodname" + x);
method.setAccessible(true); // Only needed if it's not accessible from calling class.
method.invoke(yourClass); // Assuming your method doesn't take any arguments.
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
System.err.println("Method methodname" + x + "is not declared.");
e.printStackTrace();
}
}

Related

Invoking a method in anonymous (inner) classes

interface Example{
void methodExample();
}
class Y{
void do(Example x) { }
}
class X{
void methodX() {
Y y = new Y();
y.do(new Example() {
public void methodExample() {
System.out.println("methodExample");
}
});
}
}
I want to create a main class and call methodExample. How would I do that?
Since your class implements Example interface, and because void methodExample() is present on that interface, all you need to do is to reference the object by its interface, and call its method:
class Y{
public void doIt(Example x) {
x.methodExample();
}
}
The above works, because objects of all classes implementing Example, including all anonymous implementations, are known at compile time to implement methodExample().
If you don't have access to class Y then, the only way to do is to override doIt() itself first, using anonymous inner class and then, call the overridden method, e.g.:
class X {
void methodX() {
Y y = new Y() {
#Override
void doIt(Example x) {
x.methodExample();
}
};
y.doIt(new Example() {
public void methodExample() {
System.out.println("methodExample");
}
});
}
}
To call this, you can simply do:
public static void main(String[] args) throws Exception {
X x = new X();
x.methodX();
}

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));

Sad logic on types

Code base is littered with code like this:
BaseRecord record = // some BaseRecord
switch(record.source()) {
case FOO:
return process((FooRecord)record);
case BAR:
return process((BarRecord)record);
case QUUX:
return process((QuuxRecord)record);
.
. // ~25 more cases
.
}
and then
private SomeClass process(BarRecord record) { }
private SomeClass process(FooRecord record) { }
private SomeClass process(QuuxRecord record) { }
It makes me terribly sad. Then, every time a new class is derived from BaseRecord, we have to chase all over our code base updating these case statements and adding new process methods. This kind of logic is repeated everywhere, I think too many to add a method for each and override in the classes. How can I improve this?
First solution: good old polymorphism.
Simply add an abstract process() method to the BaseRecord class, and override it in every subclass. The code will thus become:
BaseRecord record = ...;
record.process();
If you can't add the process() method into the BaseRecord class (and its subclasses), then implement the visitor pattern. It will leave the process method outside of the BaseRecord class, but each time you add a new subclass, you'll be forced to modify the Visitor interface, and all its implementations. The compiler will thus check for you that you haven't forgotten a case somwhere in a switch.
public interface RecordVisitor<T> {
T visitFoo(FooRecord foo);
T visitBar(BarRecord foo);
...
}
public abstract class BaseRecord {
public abstract <T> T accept(RecordVisitor<T> visitor);
}
public class FooRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitFoo(this);
}
}
public class BarRecord extends BaseRecord {
#Override
public <T> T accept(RecordVisitor<T> visitor) {
return visitor.visitBar(this);
}
}
Now you simply have to implement RecordVisitor for each block of logic described in the question:
RecordVisitor<Void> visitor = new ProcessRecordVisitor();
record.accept(visitor);
Both Visitor Pattern and Strategy pattern can be put in use here. http://en.wikipedia.org/wiki/Strategy_pattern and http://en.wikipedia.org/wiki/Visitor_pattern
I think this is instructive:
package classplay;
public class ClassPlay
{
public void say(String msg) { System.out.println(msg); }
public static void main(String[] args)
{
ClassPlay cp = new ClassPlay();
cp.go();
}
public void go()
{
A someClass = new C();
say("calling process with double dispatch");
someClass.dueProcess(this);
say("now calling process directly");
process(someClass);
}
public void process(A a)
{
say("processing A");
a.id();
}
public void process(B b)
{
say("processing B");
b.id();
}
public void process(C c)
{
say("processing C");
c.id();
}
abstract class A
{
abstract public void id(); // { System.out.println("Class A"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class B extends A
{
public void id() { System.out.println("Class B"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
class C extends A
{
public void id() { System.out.println("class C"); }
public void dueProcess(ClassPlay cp) { cp.process(this); }
}
}

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.

Is it possible to have an enum that contains constructors for objects?

I'm testing out a different sort of pattern. I've already got the code working in a switch statement, but I'd like to try something a little more ecclectic... for research purposes.
Say I have 4 classes, Class1, Class2, Class3, and Class4 that all extend BaseClass. I want to put them into an enum, like so:
enum ClassFactories {
Class1(Class1.class),
Class2(Class2.class),
Class3(Class3.class),
Class4(Class4.class);
private final Class factory;
ClassFactories(Class factory) {
this.factory = factory;
}
public BaseClass generate() {
BaseClass b = null;
try {
b = (BaseClass)this.factory.newInstance();
} catch (Exception e) {
// handle any exceptions
}
return f;
}
}
In a factory method that is passed an int, I want to be able to do something like this:
public void fakeMethod(int type) {
BaseClass someClass = ClassFactories.values()[type].generate();
someClass.doStuff();
}
Is there a cleaner/easier way of doing this? I'm not so much concerned with readability (right now), I'm just curious if this is possible.
Yes, this is possible. Something like a 'Template Method' approach. So for example
public enum ClassFactory {
Class1() {
#Override public void generate() {
System.out.println("I'm in Class 1.");
}
},
Class2() {
#Override public void generate() {
System.out.println("I'm in Class 2.");
}
};
//template method
public abstract void generate();
private static final Map<Integer, ClassFactory > lookup
= new HashMap<Integer, ClassFactory >();
static {
for (ClassFactory s : EnumSet.allOf(ClassFactory.class))
lookup.put(s.getIntValue(), s);
}
public static ClassFactory getValue(int intValue) {
return lookup.get(intValue);
}
}
INVOCATION CODE
With the use of static imports, the client code calling this enumeration would look like:
Class1.generate();
Class2.generate();
//or better...
getClass().generate();
Or
public void fakeMethod(int type) {
ClassFactory.getValue(type).generate();
}

Categories

Resources