Edit an object's methods after they've been created in Java - java

In JavaScript one can create and edit an object's functions on the fly. Is this possible with a Java object's methods? I am essentially wanting something like this:
public class MyObject{
private int x;
public MyObject(){x = 0;}
public myMethod(){}
}
MyObject foo = new MyObject();
and later call something along the lines of:
foo.myMethod = new method({x = 42;});

It's not directly possible, but you could try something like this:
public class MyObject {
private int x;
interface MyMethod {
void call();
}
public MyObject() {
x = 0;
}
public MyMethod myMethod = new MyMethod() {
#Override
public void call() {
x = 42;
}
};
}

You can't edit it in the way that you are trying to demonstrate above, the closest thing you could do to emulate it would be to intercept the method. The only way I could think of at the current moment is to use a MethodInterceptor found within the cglib library to intercept the method.

In Java you cannot do this like you would do it in Javascript.
But in Java you can achieve such an behavior using the Strategy pattern.
For example,
public interface Strategy {
void doSomething(MyObject obj);
}
public class BasicStrategy implements Strategy {
public void doSomething(MyObject obj) {
//do something
}
}
public class AnotherStrategy implements Strategy {
public void doSomething(MyObject obj) {
obj.setX(42);
}
}
public class MyObject {
private Strategy actualStrategy = new BasicStrategy();
private int x = 0;
public void executeStrategy() {
actualStrategy.doSomething(this);
}
public void setStrategy(Strategy newStrategy) {
actualStrategy = newStrategy;
}
public void setX(int x) {
this.x = x;
}
}
You can alter the behavior of the method at runtime using the following code.
MyObject obj = new MyObject();
obj.setStrategy(new AnotherStrategy());
obj.executeStrategy();

Yes, it's theoretically possible, but you don't want to do it. This sort of thing is black magic, and if you need to ask the question, you're several years from being ready to work with it.
That said, what you're trying to accomplish may be workable with the Strategy design pattern. The idea here is that you define an interface that has the method(s) you need to swap out (say, calculate()), and the class whose behavior you want to change has a field of that interface. You can then modify the contents of that field.
public interface Calculator {
double calculate(double x, double y);
}
public class MathStuff {
private Calculator calc;
...
public void doStuff() {
...
result = calc.calculate(x, y);
...
}
}
public class Add implements Calculator {
public double calculate(double x, double y) {
return x + y;
}
}

You cannot do this. In java new method is made to return the instance of class Object, not methods. And one thing is to understand is Javascript is an functional programming language and Java is a object oriented language. You cannot treat a method as object in java, also it breaks the security of java encapsulation.

Related

Making a static duplicate of non-static integer

For my programming class in first year engineering I have to make a D-game in Java, with only very little knowledge of Java.
In one class I am generating a random integer via
public int rbug = (int)(Math.random() * 18);
every so many ticks. I have to use this integer in another class (in the requirements for an if-loop), and apparently it needs to be static. But when I change the variable to public int static, the value doesn't change any more.
Is there an easy way to solve this problem?
Edit: part of code added:
public int rbug = (int)(Math.random() * 18);
which is used in
public void render(Graphics g){
g.drawImage(bugs.get(rbug), (int)x, (int)y, null);
And in another class:
if(Physics.Collision(this, game.eb, i, BadBug.rbug)){
}
As error for BadBug.rbug I get the message
Cannot make a static reference to a non-static field
Using static to make things easier to access is not a very good ideal for design. You would want to make variables have a "getter" to access them from another class' instance, and possibly even a "setter". An example of this:
public class Test {
String sample = 1337;
public Test(int value) {
this.sample = value;
}
public Test(){}
public int getSample() {
return this.sample;
}
public void setSample(int setter) {
this.sample = setter;
}
}
An example of how these are used:
Test example = new Test();
System.out.println(example.getSample()); // Prints: 1337
example = new Test(-1);
System.out.println(example.getSample()); // Prints: -1
example.setSample(12345);
System.out.println(example.getSample()); // Prints: 12345
Now you might be thinking "How do I get a string from the class that made the instance variable within the class?". That's simple as well, when you construct a class, you can pass a value of the class instance itself to the constructor of the class:
public class Project {
private TestTwo example;
public void onEnable() {
this.example = new TestTwo(this);
this.example.printFromProject();
}
public int getSample() {
return 1337;
}
}
public class TestTwo {
private final Project project;
public TestTwo(Project project) {
this.project = project;
}
public void printFromProject() {
System.out.println(this.project.getSample());
}
}
This allows you to keep single instances of classes by passing around your main class instance.
To answer the question about the "static accessor", that can also be done like this:
public class Test {
public static int someGlobal = /* default value */;
}
Which allows setting and getting values through Test.someGlobal. Note however that I would still say that this is a horrible practice.
Do you want to get a new number every time that you want BadBug.rbug? Then convert it from a variable to a method.

Pass an object of another class to a singleton class

I am using this singleton class in Java and in one method, I need an object of a class which gets instantiated in Main. I am not knowing how to pass that object to this method because this code is written in the constructor of the singleton class as I need it to be executed as soon as the program starts.
Should I take out the code from the constructor and make it a standalone method which I call from Main (though I wouldn't prefer this) or is there another way?
Any ideas?
Code:
Main:
public static void main(String[] args) {
X x; // This is the object I need to pass to the singleton class
}
Singleton class:
public SomeSingletonClass {
private Queue<Y> someQueue; // Y is another class I have in my project
private SomeSingletonClass(){
someQueue.add(new Y(<some data>, <some data>, <here I need an object of X as the constructor needs it>);
}
}
I haven't added the entire code. Just a fragment where I am stuck.
You have two main options.
The first will produce howls of derision - and rightly so because it is a dark tunnel of hell.
public class X {
}
public class Y {
public Y(String s, X x) {
}
}
public class Main {
public static X x = new X();
}
public class SomeSingletonClass {
private Queue<Y> someQueue = new LinkedList<>();;
private SomeSingletonClass() {
someQueue.add(new Y("Hello", Main.x));
}
}
Here we make the X created by Main a public static so it is now, essentially, global state in parallel with your singleton.
Most readers will understand how nasty this is but it is the simplest solution and therefore often the one taken.
The second option is lazy construction.
public class BetterSingletonClass {
private BetterSingletonClass me = null;
private Queue<Y> someQueue = new LinkedList<>();
private BetterSingletonClass(X x) {
someQueue.add(new Y("Hello", x));
}
public BetterSingletonClass getInstance (X x) {
if ( me == null ) {
me = new BetterSingletonClass(x);
}
return me;
}
}
Note that I have made no effort to make this a real singleton, n'or is this thread-safe. You can search for thread safe singleton elsewhere for plenty of examples.

How to call a public method WITHIN a private attribute?

I am new to Java. So the question may seem naive... But could you please help?
Say for example, I have a class as follows:
public class Human {
private float height;
private float weight;
private float hairLength;
private HairState hairTooLong = new HairState() {
#Override
public void cut(Human paramHuman) {
Human.this.decreaseHairLength();
}
#Override
public void notCut(Human paramHuman) {
Human.this.increaseHairLength();
}
};
public float increaseHairLength () {
hairLength += 10;
}
public float decreaseHairLength () {
hairLength -= 10;
}
private static abstract interface HairState {
public abstract void cut(Human paramHuman);
public abstract void notCut(Human paramHuman);
}
}
Then I have another class as follow:
public class Demo {
public static void main(String[] args) {
Human human1 = new Huamn();
Human.HairState.cut(human1);
}
}
The statement
Human.HairState.cut(human1);
is invalid...
I intend to call the public cut() function, which belongs to hairTooLong private attribute.
How should I do it?
Since HairState is private to Human, nothing outside the Human class can even know about it.
You can create a method in Human that relays the call to its private mechanism:
public class Human {
. . .
public float cutHair() {
return hairTooLong.cut(this);
}
}
and then call that from main():
System.out.println(human1.cutHair());
Two other solutions to previous comment:
You can implement a getter which returns the hairTooLong attribute.
You can invoke the the cut() method through the reflection API (but you don't want to go there if you are beginner).
Would suggest either the solution in the previous comment, or the first option presented here.
If you are curious, you can have a look to the reflection API and an example here: How do I invoke a Java method when given the method name as a string?
In java there are four access levels, default, private, public and protected. Visibility of private is only limited to a certain one class only (even subclass cannot access). You cannot call private members in any other class. Here is a basic details of java access levels.
Access Levels
Modifier Class Package Subclass World
public Y Y Y Y
protected Y Y Y N
no modifier Y Y N N
private Y N N N
For more details check Oracle docs

Class for Strong References in Java, for anonymous classes

I want a hard reference class in my Java code, but, of course, there isn't one. Is there some other way to do what I want, or should I make my own class?
This comes up with anonymous classes in methods where I want the anonymous class to set the return value for the method.
For example, given
interface Greeting {
void greet();
}
I want code like the following:
// Does not compile
static void hello(final String who) {
String returnValue;
Greeting hello = new Greeting() {
public void greet() {
returnValue = "hello" + who;
}
};
hello.greet();
System.out.println(returnValue);
}
I can fake it using a list:
static void hello(final String who) {
final List<String> returnValue = new ArrayList<String>();
Greeting hello = new Greeting() {
public void greet() {
returnValue.add("hello" + who);
}
};
hello.greet();
System.out.println(returnValue.iterator().next());
}
But I want to not use a list. I can write a StrongReference class that solves this:
static class StrongReference<T> {
private T referent;
public void set(T referent) {
this.referent = referent;
}
public T get() {
return referent;
}
}
which makes my method clearer:
static void hello(final String who) {
final StrongReference<String> returnValue = new StrongReference<String>();
Greeting hello = new Greeting() {
public void greet() {
returnValue.set("hello" + who);
}
};
hello.greet();
System.out.println(returnValue.get());
}
For my contrived example, I could have greet() return a String, but I'm working with much more complex classes, where the setting is deep within a database call that the base class manages. The instances have many different types they want to return, so I've just been using the List trick.
My questions are: Is there a better way to do this? What's wrong with my StrongReference class? Has anyone written a StrongReference in a library somewhere?
If you want something from the standard API, perhaps an AtomicReference would do?
It has void set(V value) and a V get() methods. Unless you have multiple threads involved, just see the synchronization mechanism as a bonus ;-)
A common idiom
final String[] result = { null };
result[0] = ...;
Looks good but I think you should make some kind of synchronization since another thread might set the value.

General OO question about inheritance and extensibility

So, in a single parent inheritance model what's the best solution for making code extensible for future changes while keeping the same interface (I'd like to emphasize the fact that these changes cannot be known at the time of the original implementation, the main focus of my question is to explore the best mechanism/pattern for supporting these changes as they come up)? I know that this is a very basic OO question and below I provide example of how I've been going about it, but I was wondering if there a better solution to this common problem.
Here's what I've been doing (the example code is in Java):
In the beginning, the following two classes and interface are created:
public class Foo
{
protected int z;
}
public interface FooHandler
{
void handleFoo(Foo foo);
}
public class DefaultFooHandler implements FooHandler
{
#Override
public void handleFoo(Foo foo)
{
//do something here
}
}
The system uses variables/fields of type FooHandler only and that object (in this case DefaultFooHandler) is created in a few, well-defined places (perhaps there's a FooHandlerFactory) so as to compensate for any changes that might happen in the future.
Then, at some point in the future a need to extend Foo arises to add some functionality. So, two new classes are created:
public class ImprovedFoo extends Foo
{
protected double k;
}
public class ImprovedFooHandler extends DefaultFooHandler
{
#Override
public void handleFoo(Foo foo)
{
if(foo instanceof ImprovedFoo)
{
handleImprovedFoo((ImprovedFoo)foo);
return;
}
if(foo instanceof Foo)
{
super.handleFoo(foo);
return;
}
}
public void handleImprovedFoo(ImprovedFoo foo)
{
//do something involving ImprovedFoo
}
}
The thing that makes me cringe in the example above is the if-statements that appear in ImprovedFooHandler.handleFoo
Is there a way to avoid using the if-statements and the instanceof operator?
First of all the code you wrote won't work.
Each time you see instanceof and if...else together be very careful. The order of these checks is very important. In your case you'll never execute handleImpovedFoo. Guess why :)
It's absolutely normal you have these instanceof statements. Sometimes it's the only way to provide different behavior for a subtype.
But here you can use another trick: use simple Map. Map classes of foo-hierarchy to instances of fooHandler-hierarchy.
Map<Class<? extends Foo>, FooHandler> map ...
map.put( Foo.class, new FooHandler() );
map.put( ImprovedFoo.class, new ImprovedFooHandler() );
Foo foo ...; // here comes an unknown foo
map.get( foo.getClass() ).handleFoo( foo );
The best way of handling this depends too much on the individual case to provide a general solution. So I'm going to provide a number of examples and how I would solve them.
Case 1: Virtual File System
Clients of your code implement virtual file systems which enable them to operate any sort of resource which can be made to look like a file. They do so by implementing the following interface.
interface IFolder
{
IFolder subFolder(String Name);
void delete(String filename);
void removeFolder(); // must be empty
IFile openFile(String Name);
List<String> getFiles();
}
In the next version of your software you want to add the ability to remove a directory and all it contents. Call it removeTree. You cannot simply add removeTree to IFolder because that will break all users of IFolder. Instead:
interface IFolder2 implements IFolder
{
void removeTree();
}
Whenever a client registers an IFolder (rather then IFolder2), register
new IFolder2Adapter(folder)
Instead, and use IFolder2 throughout your application. Most of your code should not be concerned with the difference about what old versions of IFolder supported.
Case 2: Better Strings
You have a string class which supports various functionality.
class String
{
String substring(int start, end);
}
You decide to add string searching, in a new version and thus implement:
class SearchableString extends String
{
int find(String);
}
That's just silly, SearchableString should be merged into String.
Case 3: Shapes
You have a shape simulation, which lets you get the areas of shapes.
class Shape
{
double Area();
static List<Shape> allShapes; // forgive evil staticness
}
Now you introduce a new kind of Shape:
class DrawableShape extends Shape
{
void Draw(Painter paint);
}
We could add a default empty Draw method to Shape. But it seems incorrect to have Shape have a Draw method because shapes in general aren't intended to be drawn. The drawing really needs a list of DrawableShapes not the list of Shapes that is provided. In fact, it may be that DrawableShape shouldn't be a Shape at all.
Case 4: Parts
Suppose that we have a Car:
class Car
{
Motor getMotor();
Wheels getWheels();
}
void maintain(Car car)
{
car.getMotor().changeOil();
car.getWheels().rotate();
}
Of course, you know somewhere down the road, somebody will make a better car.
class BetterCar extends Car
{
Highbeams getHighBeams();
}
Here we can make use of the visitor pattern.
void maintain(Car car)
{
car.visit( new Maintainer() );
}
The car passes all of its component parts to calls into ICarVisitor interface allowing the Maintainer class to maintain each component.
Case 5: Game Objects
We have a game with a variety of objects which can be seen on screen
class GameObject
{
void Draw(Painter painter);
void Destroy();
void Move(Point point);
}
Some of our game objects need the ability to perform logic on a regular interval, so we create:
class LogicGameObject extends GameObject
{
void Logic();
}
How do we call Logic() on all of the LogicGameObjects? In this case, adding an empty Logic() method to GameObject seems like the best option. Its perfectly within the job description of a GameObject to expect it to be able to know what to do for a Logic update even if its nothing.
Conclusion
The best way of handling this situations depends on the individual situation. That's why I posed the question of why you didn't want to add the functionality to Foo. The best way of extending Foo depends on what exactly you are doing. What are you seeing with the instanceof/if showing up is a symptom that you haven't extended the object in the best way.
In situations like this I usually use a factory to get the appropriate FooHandler for the type of Foo that I have. In this case there would still be a set of ifs but they would be in the factory not the implementation of the handler.
Yes, don't violate LSP which is what you appear to be doing here. Have you considered the Strategy pattern?
This looks like a plain simple case for basic polymorphism.Give Foo a method named something like DontWorryI'llHandleThisMyself() (um, except without the apostrophe, and a more sensible name). The FooHandler just calls this method of whatever Foo it's given. Derived classes of Foo override this method as they please. The example in the question seems to have things inside-out.
With the visitor pattern you could do something like this,
abstract class absFoo {}
class Foo extends absFoo
{
protected int z;
}
class ImprovedFoo extends absFoo
{
protected double k;
}
interface FooHandler {
void accept(IFooVisitor visitor, absFoo foo);
}
class DefaultFooHandler implements FooHandler
{
public void accept(IFooVisitor visitor, absFoo foo)
{
visitor.visit(this, foo);
}
public void handleFoo(absFoo foo) {
System.out.println("DefaultFooHandler");
}
}
class ImprovedFooHandler implements FooHandler
{
public void handleFoo(absFoo foo)
{
System.out.println("ImprovedFooHandler");
}
public void accept(IFooVisitor visitor, absFoo foo) {
visitor.visit(this, foo);
}
}
interface IFooVisitor {
public void visit(DefaultFooHandler fooHandler, absFoo foo);
public void visit(ImprovedFooHandler fooHandler, absFoo foo);
}
class FooVisitor implements IFooVisitor{
public void visit(DefaultFooHandler fHandler, absFoo foo) {
fHandler.handleFoo(foo);
}
public void visit(ImprovedFooHandler iFhandler, absFoo foo) {
iFhandler.handleFoo(foo);
}
}
public class Visitor {
public static void main(String args[]) {
absFoo df = new Foo();
absFoo idf = new ImprovedFoo();
FooHandler handler = new ImprovedFooHandler();
IFooVisitor visitor = new FooVisitor();
handler.accept(visitor, idf);
}
}
But this does not guarantee only Foo can be passed to DefaultFooHandler. It allows ImprovedFoo also can be passed to DefaultFooHandler. To overcome, something similar can be done
class Foo
{
protected int z;
}
class ImprovedFoo
{
protected double k;
}
interface FooHandler {
void accept(IFooVisitor visitor);
}
class DefaultFooHandler implements FooHandler
{
private Foo iFoo;
public DefaultFooHandler(Foo foo) {
this.iFoo = foo;
}
public void accept(IFooVisitor visitor)
{
visitor.visit(this);
}
public void handleFoo() {
System.out.println("DefaultFooHandler");
}
}
class ImprovedFooHandler implements FooHandler
{
private ImprovedFoo iFoo;
public ImprovedFooHandler(ImprovedFoo iFoo) {
this.iFoo = iFoo;
}
public void handleFoo()
{
System.out.println("ImprovedFooHandler");
}
public void accept(IFooVisitor visitor) {
visitor.visit(this);
}
}
interface IFooVisitor {
public void visit(DefaultFooHandler fooHandler);
public void visit(ImprovedFooHandler fooHandler);
}
class FooVisitor implements IFooVisitor{
public void visit(DefaultFooHandler fHandler) {
fHandler.handleFoo();
}
public void visit(ImprovedFooHandler iFhandler) {
iFhandler.handleFoo();
}
}
public class Visitor {
public static void main(String args[]) {
FooHandler handler = new DefaultFooHandler(new Foo());
FooHandler handler2 = new ImprovedFooHandler(new ImprovedFoo());
IFooVisitor visitor = new FooVisitor();
handler.accept(visitor);
handler2.accept(visitor);
}
}

Categories

Resources