Lets say I have class like:
class A
{
}
by any means I can make the class implements an interface on the runtime?
This is what I'm trying to achieve, when some one creates object of class A, I need to intercept the calls to that object.
Very new to Java, thanks.
A class cannot be made to implement an interface at runtime. The best that can be done at runtime is creating a dynamic subclass of your class, which additionally implements an interface.
By the Liskov Substitution Principle this solution will work quite well because any code written against your type A will also work against its subtypes. Also, any code written against the interface you are implementing will also work and be able to access the behavior implemented in your class A, to the extent to which this behavior is reflected through the behavior of the interface's methods.
You can do this with Instrumentation, however I wouldn't do this unless you know Java AND Byte Code very well and there really isn't another option.
A better option is to use composition or inheritance
class A {
}
class B extend A implement I {
// B is an A and implements I
}
A a = new B();
class C implement I {
A a;
}
Either B or C implement your interface without having to change A.
You can use a Proxy object to adapt any object at run time to make it appear as if it implements an interface.
There is a nice article here that discusses a factory method for doing this to objects.
Essentially, a Proxy object can be used to wrap an object by intercepting all method calls to the object and redirecting them dynamically.
This should be solvable with an adapter. Have an other class defined that implements your interface and delegates to the real object:
class YourAdapter implements YourInterface {
private final YourClass realObject;
public YourAdapter(YourClass realObject) {
this.realObject = realObject;
}
#Override
public methodFromInterface() {
realObject.methodFromInterface();
}
// .......
}
Now, given a method that expects YourInterface and an object of type YourClass:
void someMethod(YourInterface param) {}
void test() {
YourClass object = getFromSomewhere();
someMethod( YourAdapter(object) );
}
2nd way :
Using Proxy class :
Refer this link.
Example of dynamically implement an interface using Dynamic Proxy
Related
There are several classes (which I can't edit) which implement an interface, is it possible to add a method that only calls methods defined in the interface to each class that implements that interface?
(without java 8)
No, I don't believe so. Such a method would have to realized in the concrete class as a real method, but without access to the classes themselves you can't do that.
You might create subclasses of each, and all those subclasses could implement you new interface with the new method.
I'm not sure if I get you right but if classes A, B, C, ... implement an interface I and you can not edit A, B, C, ... and want to add a method you propably could just extend each class with a new subclass and each subA, subB, subC and so on could implement the new method...
If you are using Java 8 and can modify the interface, then yes:
interface Face {
Object existing();
default Object additional() {
return "Hello " + existing() + "!";
}
}
Otherwise, no, you cannot. Java does not have a feature like Javascript prototypes, C# extension methods, etc at this time.
Just write a static method that takes in the interface type and calls the methods:
interface Fooable
{
void foo();
}
public class FooableExtensions
{
public static void doSomethingToFooable( Fooable f /*, other parameters*/ )
{
f.foo();
}
}
It doesn't have the fancy syntactic-sugar that C# extension methods provide, but it should do the trick.
I don't think there is a way to do what you are asking, not without resorting to byte code manipulation anyway.
Perhaps AOP would help, you could add a point cut to the target methods of the interface.
I already read the post of research effort required to post a SO question. I am ashamed again to post this question to a pile of million questions. But I still don't get the idea of interfaces in java. They have unimplemented methods and then defined for every class in which they are implemented. I searched about it. Interfaces were used to support multiple inheritance in java and also to avoid (Deadly) Diamond Death of inheritance. I also came across Composition vs Inheritance and that inheritance is not for code reuse and its for polymorphism. So when I have a common code as a class to extend it will not be supported due to multiple inheritance which gives the option to use Interfaces(Correct me if I am wrong). I also came across that its not possible in most cases to define a generic implementation. So what is the problem in having a common definition (not a perfect generic implementation) of the interface method and then Override it wherever necessary and why doesn't java support it. Eg. When I have 100 classes that implements an interface 70 of them have a common implementation while others have different implementation. Why do I have to define the common method in interface over 70 classes and why can't I define them in Interface and then override them in other 30 classes which saves me from using same code in 70 classes. Is my understanding of interfaces wrong?
First, an interface in Java (as of Java 7) has no code. It's a mere definition, a contract a class must fulfill.
So what is the problem in having a common definition (not a perfect
generic implementation) of the interface method and then Override it
wherever necessary and why doesn't java support it
Yes you can do that in Java, just not with interfaces only. Let's suppose I want from this Example interface to have a default implementation for method1 but leave method2 unimplemented:
interface Example {
public void method1();
public String method2(final int parameter);
}
abstract class AbstractExampleImpl implements Example {
#Override
public void method1() {
// Implement
}
}
Now classes that want to use this method1 default implementation can just extend AbstractExampleImpl. This is more flexible than implementing code in the interface because if you do so, then all classes are bound to that implementation which you might not want. This is the advantage of interfaces: being able to reference a certain behavior (contract) without having to know how the class actually implements this, for example:
List<String> aList = MyListFactory.getNewList();
MyListFactory.getNewList() can return any object implementing List, our code manipulating aList doesn't care at all because it's based on the interface.
What if the class that uses interface already is a Sub-class. Then we
can't use Abstract class as multiple inheritance is not supported
I guess you mean this situation:
class AnotherClass extends AnotherBaseClass
and you want to extend AbstractExampleImpl as well. Yes, in this case, it's not possible to make AnotherClass extend AbstractExampleImpl, but you can write a wrapped inner-class that does this, for example:
class AnotherClass extends AnotherBaseClass implements Example {
private class InnerExampleImpl extends AbstractExampleImpl {
// Here you have AbstractExampleImpl's implementation of method1
}
}
Then you can just internally make all Example methods being actually implemented by InnerExampleImpl by calling its methods.
Is it necessary to have the interface in AnotherClass?
I guess you mean AnotherClass implements Example. Well, this is what you wanted: have AnotherClass implement Example with some default implementation as well as extend another class, or I understood you wrong. Since you cannot extend more than one class, you have to implement the interface so you can do
final Example anotherClass = new AnotherClass();
Otherwise this will not be possible.
Also for every class that implements an interface do I have to design
an inner class?
No, it doesn't have to be an inner class, that was just an example. If you want multiple other classes have this default Example implementation, you can just write a separate class and wrap it inside all the classes you want.
class DefaultExampleImpl implements Example {
// Implements the methods
}
class YourClass extends YetAnotherClass implements Example {
private Example example = new DefaultClassImpl();
#Override
public void method1() {
this.example.method1();
}
#Override
public String method2(final int parameter) {
return this.example.method2(parameter);
}
}
You can create an abstract class to implement that interface, and make your those classes inherit that abstract class, that should be what you want.
A non abstract class that implements and interface needs to implement all the methods from the interface. A abstract class doesn't have to implement all the methods but cannot initiated. If you create abstract class in your example that implements all the interface methods except one. The classes that extend from these abstract class just have to implement the one not already implemented method.
The Java interfaces could have been called contracts instead to better convey their intent. The declarer promise to provide some functionality, and the using code is guaranteed that the object provides that functionality.
This is a powerful concept and is decoupled from how that functionality is provided where Java is a bit limited and you are not the first to notice that. I have personally found that it is hard to provide "perfect" implementations which just need a subclass or two to be usable in a given situation. Swing uses adapters to provide empty implementations which can then be overrides as needed and that may be the technique you are looking for.
The idea of the interface is to create a series of methods that are abstract enough to be used by different classes that implement them. The concept is based on the DRY principle (Don't repeat yourself) the interface allows you to have methods like run() that are abstract enough to be usuable for a game loop, a players ability to run,
You should understand the funda of interface first. Which is
It is use to provide tight coupling means tight encapsulation
It helps us to hide our code from the external environment i.e. from other class
Interface should have only definition and data which is constant
It provide facility to class open for extension. Hence it cannot be replace by the any other class in java otherwise that class will become close for extension. which means class will not be able to extend any other class.
I think you are struggling with the concept of Object Oriented Design more than anything. In your example above where you state you have 100 classes and 70 of them have the same method implementation (which I would be stunned by). So given an interface like this:
public interface Printable
{
void print();
}
and two classes that have the "same" implementation of print
public class First implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
public class Second implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
you would instead want to do this:
public abstract class DefaultPrinter implements Printable
{
public void print()
{
System.out.println("Hi");
}
}
now for First and Second
public class First extends DefaultPrinter
{
}
public class Second extends DefaultPrinter
{
}
Now both of these are still Printable . Now this is where it gets very important to understand how to properly design object hierarchies. If something IS NOT a DefaultPrinter YOU CANNOT AND SHOULD NOT make the new class extend DefaultPrinter
I have two classes A and B which both implment the interface Z. Now, class A should for some functions of Interface Z (Z.f1, Z.f2, Z.f3, ...) only work as dispatcher to an object of class B.
public class A implements Z{
private B b; //instantiated in constructor of A
#Override
public String f1(int p)
{
return b.f1(p);
}
...
Is there a generic way to do this in Java?
If you mean that method f1() is declared in interface Z the pattern you want to implement is called wrapper or decorator.
In java you can create generic implementation using dynamic proxy introduced to java 1.4.
I don't think so. But sometimes your IDE can assist in creating all the simple methods to delegate the calls. And sometimes you can find third part classes to do this. For example, Guava (http://code.google.com/p/guava-libraries/) has a ton of ForwardingXXX classes, which, by default, delegate everything to something else. For example, ForwardingMap delegates all calls to another Map. You need to override the methods that you do NOT want to delegate.
I would like to override a 3rd party, open-source final class's non-final method.
final class A
{
void put(obj a)
{...}
obj get()
{...}
}
Please tell me how to override the get() and put() methods, yet still retain the other behaviour and functionality of this class.
It's open source: fork it, and make the class non-final.
You won't be able to extend it without making it non-final.
If your class has a defined interface in which put and get methods are defined then You may want to try to proxy the class.
The easiest way is to create something like this:
public interface CommonInterface {
void put(); Object get();
}
final class A implements CommonInterface
{
void put(obj a)
{...}
obj get()
{...}
}
public class ProxyToA implements CommonInterface{
private A a;
void put(Object a){
// your override functionality
}
Object get(){
// same here
}
void otherAStuff(){
a.otherAStuff();
}
}
And then just use CommonInterface and proxy your object. Or you can use JDK proxies, javassist, etc.
You can't extend final class. Per Java spec.
You should definitely try to find out why the class is final. If you are able to convince yourself it is ok to do that, another options is to use AspectJ to just change the behavior of thse two methods.
AspectJ allows you to modify behavior of specific methods. It can do this even for private methods -- security constraints permitting -- and access and assign private fields of the class.
The short answer is that you cannot override the methods because you cannot extend the class. What are you planning to do with the get and put methods by overriding? If you are looking add some functionality to those methods, you can create another class which wraps around this class.
I saw this Java snippet in the book Spring in Action, but I'm not familiar with the language construct.
new RowMapper() {
public Object mapRow() throws SQLException, DataAccessException {
Motorist motorist = new Motorist();
motorist.setId(rs.getInt(1));
motorist.setEmail(rs.getString(2));
motorist.setPassword(rs.getString(3));
motorist.setFirstName(rs.getString(4));
motorist.setLastName(rs.getString(5));
return motorist;
}
}
According the Spring documentation, RowMapper is an interface. It looks to me like an anonymous class definition based on the RowMapper interface. The new keyword is a little confusing, making me wonder if this also creates one instance of the anonymous class. I would guess yes, because if the class has no name, how will you ever create an instance after the line that defines it?
Can anyone confirm my guesses that:
this is an anonymous class definition based on the RowMapper interface, and
it creates a single instance of that class?
This is an anonymous class definition based on the RowMapper interface
That's precisely what it is.
It creates a single instance of that class?
Yep. That's correct.
That code is implementing the interface in an anonymous way.
The syntax would be similar to:
Runnable runnable = new Runnable() {
public void run() {
}
};
Note the semicolon at the end of the declaration. Here the runnable object, though holds the reference to the Runnable interface actually contains the implemented object. That's runtime polymorphism for you!
Your guesses are entirely correct. An anonymous class definition may be based on either a non-final class or on an interface, and you must implement all abstract (or interface) methods. The only available syntax for declaring anonymous classes is new, which also has the effect of instantiating exactly one instance of the anonymous class (in the course of the program, though, many instances of the same anonymous class could be created, if this code is executed several times).
Interface tells what methods the built class instance should have or if thy are label interfaces, then what kind of behavior to associate with it.
Anonymous classes are classes that basically while instantiating a class instance thy are also extending it with custom code. So if you are instantiating a interface, then you must write all the methods described with that interface, and as long as you do at least that much, then compiler will be happy. This is what is done here.
IS this is an anonymous class definition based on the RowMapper interface?
Yes. As you can see mapRow() function has been written. And if you debug the code you can see, that is not a class of an instance of interface, but class that extends interface. In case of abstract class or just class, it would be same - extended. So if class is final you cant write anonymous class for it.
Does it create a single instance of that class?
Well, it extends it and makes an instance of it. It will be single instance and any sequent call to it would result in a different class. If you debug the code, then you can even see different class names dynamically associated with it.
Solely from the code above and without knowing about RowMapper, all you can assume is that a new anonymous class based on RowMapper (which may be an interface or a class) is instantiated.
Declaring Anonymous class and in below example it creates two instances .
public class Multithread {
void test(){
new Runnable() {
#Override
public void run() {
System.out.println("1");
}
}.run();
new Runnable() {
#Override
public void run() {
System.out.println("11");
}
}.run();}
public static void main(String[] args) {
new Multithread().test();
}
}