Assume I have an interface with a class embedded in it (the purpose being that this interface must provide a 'type'. The interface has some methods using that 'type'. So, in file S.java, I have
public interface S {
public class SType
{
}
public abstract void f( SType a );
}
I want to implement this interface, and I try this, in file SS.java:
public final class SS implements S
{
public class SType extends java.util.HashSet<Integer>
{
}
public void f( SType a )
{
// ...
}
}
However, when I try to compile these files ("javac S.java SS.java"), I get the usual error message "SS is not abstract and does not override abstract method f(SType) in S" indicating that "f()" in the concrete class is not a proper implementation of "f()" in the interface. Why?
Try with:
public final class SS implements S{
public class SType extends java.util.HashSet<Integer>
{
}
public void f(S.SType a) {
// ..
}
}
EDIT:
Perhaps, you need this:
public interface S<SType> {
public void f( SType a );
}
public final class SS implements S<HashSet<Integer>> {
public void f(HashSet<Integer> a ){
// ...
}
}
Related
I have a class hierarchy like that:
abstract class BaseThing
{
public abstract void doSomething();
}
class Thing1 extends BaseThing
{
#Override
public void doSomething()
{
doSomethingWithThing1();
}
}
class Thing2 extends BaseThing
{
#Override
public void doSomething()
{
doSomethingWithThing2();
}
}
// A dozen more classes that extend the BaseThing class.
I need to create an extended version of the whole tree. There is no multiple inheritance in Java, so I created it as:
interface BaseThingExt
{
public void doSomethingElse();
}
class Thing1Ext extends Thing1 implements BaseThingExt
{
#Override
public void doSomethingElse()
{
doSomethingElseWithThing1();
}
}
// All Thing.. classes are extended by ThingExt... classes
Now the question. Where can I put some common fields for all ThingExt classes? I cannot place them in the base interface, as they would become final static. I cannot make BaseThingExt an abstract class as Java doesn't support a multiple inheritance. I cannot believe the only solution is to replicate them a dozen times in all ThingExt classes!
EDIT: Please note that all ThingExt classes should extend their according Thing classes and not just the BaseThing class, because there are some specifics in each derived class. So the answer by #Hamdi Douss won't work.
The usual trick is to use composition rather than inheritance:
interface BaseThingExt
{
public void doSomethingElse();
}
class ConcreteImplementation implements BaseThing, BaseThingExt {
private final BaseThing thingDelegate;
private final BaseThingExt extDelegate;
public ConcreteImplementation(BaseThing thing, BaseThingExt ext) {
this.thingDelegate = thing;
this.extDelegate = ext;
}
#Override
public void doSomething() {
thingDelegate.doSomething();
}
#Override
public void doSomethingElse() {
extDelegate.doSomethingElse();
}
}
I suggest to add a super class AbstractBaseThingExt:
abstract class AbstractBaseThingExt implements BaseThingExt
{
private Object commonField;
public Object getCommonField(){}
public Object setCommonField(Object commonField){}
}
class ThingExt extends AbstractBaseThingExt
{
public ThingExt(BaseThing base) {
this.base = base;
}
public void doSomething()
{
this.base.doSomething();
}
}
The class ThingExt should delegate implementation to base when appropriate.
I have a class in jar of which I want to invoke a method. But that method has parameter of abstract class and that abstract class is inner method of class in jar. AbstractClassA is a HIDDEN class. Here is code:
public class A{
private invokeThisMethod(AbstractClassA object){
}
public abstract class AbstractClassA {
public void update(int remaining){}
}
}
public class myClass{
//using Reflection get object of class A
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
}
Problem here is how do I create concrete implementation of AbstractClassA to pass in invoke method and get update method callbacks ?
Something like this should work:
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {... do something...}
};
objectOfClassAusingReflection.inovke("invokeThisMethod", a);
You cannot create an instance of abstract class or any interface at runtime.
Instead create an anonymous class for this.
public abstract class A {
public void fun(){....}
public abstract void absFun();
}
public class MyClass {
objectOfClassA = new A(){
public void absFun(){...}
}
}
Or you can first create implementation for that abstract classes for which you will have to create another class extending A
class AWrapper extends A {
public class ImplementationClassA extends AbstractClassA {
// override abstract functions...
}
}
Now you can use this Awrapper class
AWrapper wrapperObj = new AWrapper();
A obj = wrapperObj; // just to make it clear that A can hold wrapperObj as it is implementation of it.
A.AbstractClassA absObj = wrapperObj.new ImplementationClassA();
...
objectOfClassAusingReflection.inovke("invokeThisMethod", params)
Below code should work--
Here, i used anonymus classes for both outer and inner class and then with the help of getdeclatedMethod called your update method.
"TestAbs" is your jar class--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
public abstract class AbstractClassA {
public void update(int remaining) {
}
}
}
Then calling your jar class from "TestAbs1" like below--
public class TestAbs1 {
public static void main(String[] args) {
TestAbs.AbstractClassA abs = new TestAbs() {
AbstractClassA a = new AbstractClassA() {
public void update(int remaining) {
System.out.println("Inside update method : " + remaining);
}
};
}.a;
try {
int i = 1;
Class<?> class1 = Class.forName("app.test.mytest.TestAbs$AbstractClassA"); -- (*Getting instance of inner class*)
System.out.println(class1.getDeclaredMethod("update", int.class));
class1.getDeclaredMethod("update", int.class).invoke(abs, i);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The output i got is --
public void app.test.mytest.TestAbs$AbstractClassA.update(int)
Inside update method : 1
Answer to your Comment:-
What I understood from your comment is that, you wanted to call method from abstractClass which is hidden in outerclass.
As per my understanding, there is one way like below--
public abstract class TestAbs {
private void invokeThisMethod(AbstractClassA object) {
}
private abstract class AbstractClassA { --- your hidden class
public void update(int remaining) {
}
}
public class ImplementedClass extends AbstractClassA{ -- use implemented class here
....
...
}
}
And after that, use your ImplementedClass the same way mentioned above.
You can find reference example for private inner class here from java docs.
Note: In your question context, since your inner class and outer class is in jar, so I think it is difficult for you add implementation class in your jar.
In case, you find any alternatives, please let all knows about this;
thanks.
I have several Java interfaces/ABCs/classes:
public abstract class Target {
public abstract void fire(Load load);
}
public class HttpTarget extends Target {
#Override
public void fire(Load load) {
// ...
}
}
public interface Load {
// ...
}
public class HttpLoad implements Load {
// ...
}
// Inside a driver
Target target = testSuite.getTarget();
Load load = testSuite.getLoad();
target.fire(load);
So essentially a Target can fire() a Load. My main app Driver doesn't care about what kind of Target is returned by getTarget(), or what kind of Load is returned by getLoad(). It's job is to make sure that a load is fired.
I'd like to change the fire() method definition inside HttpTarget to:
#Override
public void fire(HttpLoad httpLoad) {
// ...
}
However when I do that, Java complains that the method override doesn't match the definition provided by its parent Target class (as Load and HttpLoad are two different things).
What's the solution here? Generics? Abstract factories? Ultimately, I want to be able to enforce that HttpTarget's fire() method can only accept HttpLoads, but still be compatible with the Driver code. Can someone provide a code example? Thanks in advance!
Yes, you would need generics:
public abstract class Target<L extends Load> {
public abstract void fire(L load);
}
public class HttpTarget extends Target<HttpLoad> {
#Override
public void fire(HttpLoad load) {
...
}
}
public interface TestSuite<L extends Load> { // or class
L getLoad();
Target<L> getTarget();
}
public class HttpTestSuite implements TestSuite<HttpLoad> {
#Override
public HttpLoad getLoad() {
...
}
#Override
public Target<HttpLoad> getTarget() {
return new HttpTarget();
}
}
The reason Java refuses to compile your HttpTarget class is because it doesn't override the Target's fire(Load) method. Indeed, a Target, by contract is supposed to accept any kind of Load as argument. And the HttpTarget's fire() method only accepts instances of HttpLoad, and thus breaks the Liskov principle. Generics are the solution to this problem.
You will have to use generics and even then it is not exactly what you want.
public interface Load<T extends Load> {
public void someMethod();
}
public class HttpLoad implements Load<HttpLoad> {
#Override
public void someMethod() {
System.out.println("Http Load");
...
}
}
public abstract class Target<T extends Load> {
public abstract void fire(Load<T> load);
}
public class HttpTarget extends Target<HttpLoad> {
#Override
public void fire(Load<HttpLoad> load) {
load.someMethod();
}
}
Now if you write
Target<HttpLoad> httpTarget = new HttpTarget();
Load<HttpLoad> httpLoad = new HttpLoad();
Load<OtherLoad> otherLoad = new OtherLoad();
Load otherLoad2 = new OtherLoad();
httpTarget.fire(httpLoad);
httpTarget.fire(otherLoad); // this doesn't compile
httpTarget.fire(otherLoad2) // this how ever compiles
I'm developing an application which builds on a class written by another developer (for which I do not have the source).
I wish to use all of the functionality of said class but also to extend it with additional functionality. Ordinarily to achieve this I would have defined an interface (MyInterface) and have extended the external class (TheirClass) from my own (MyClass) while implementing MyInterface.
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass extends TheirClass implements MyInterface {
public void myMethod1() { ... }
}
public class MyNewClass extends MyClass {
public void MyNewClassMethod() { ... }
}
The problem is complicated by the fact that:
I now wish to create a new class (MyNewClass) which adds additional functionality to MyClass but I don't want my code to be dependent on TheirClass.
I wish to be able to use my class as a parameter to the method of TheirOtherClass.
To combat this I refactored my code to instead use composition over inheritance and implementing TheirClassInterface. This works but requires me to implement many methods and delegate them to theirClassObject (in reality TheirClassInterface contains a very large number of methods).
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass implements TheirClassInterface, MyInterface {
private TheirClass theirClassObject;
public void myMethod1() { ... }
public void theirMethod1() { theirClassObject.theirMethod1(); }
public void theirMethod2() { theirClassObject.theirMethod2(); }
}
public class MyNewClass extends MyClass {
public void MyNewClassMethod() { ... }
}
My question is whether my approach is appropriate in this case and whether it could be improved upon as it seems to me that my code uses an excessive amount of delegation to get the job done.
Many thanks for any guidance anyone can give on this.
Danny
First, as java is a strongly-typed single inheritance language, you cannot escape the delegation.
But you can avoid having to write a lot of delegation CODE, by using a dirty little trick with Proxies and reflection.
Code follows
public interface Interface1 {
void m1();
}
public interface Interface2 {
void m2();
}
public class Class1 implements Interface1 {
public void m1() {
System.out.println(1);
}
}
public class Class2 implements Interface2 {
public void m2() {
System.out.println(2);
}
}
public interface MixinInterface extends Interface1, Interface2 {
}
And this is how the magic happens
package j.with.pseudo.multiple.inheritance;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MixinBuilder {
public static Object buildMixed(Class _interface, Object... impls){
InvocationHandler h = new MixinHandler(_interface.getInterfaces(), impls);
return Proxy.newProxyInstance(MixinBuilder.class.getClassLoader(),
new Class[]{_interface}, h);
}
public static void main(String[] args) {
Class1 o1 = new Class1();
Class2 o2 = new Class2();
MixinInterface almost_like_multiple_inheritance_guy =
(MixinInterface) buildMixed(MixinInterface.class, o1, o2);
almost_like_multiple_inheritance_guy.m1();
almost_like_multiple_inheritance_guy.m2();
}
private static class MixinHandler implements InvocationHandler{
private Class[] interfaces;
private Object[] impls;
public MixinHandler(Class[] interfaces, Object[] impls) {
this.interfaces = interfaces;
this.impls = impls;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
int i=0;
for(Class _interface : interfaces){
if(method.getDeclaringClass().isAssignableFrom(_interface)){
return method.invoke(impls[i], args);
}
i++;
}
// TODO Auto-generated method stub
throw new RuntimeException("Method not found: "+method);
}
}
}
Pretty cool huh? :-)
You can't not-depend on a class if you're extending it; it's like having a definition of Human, which does not depend on the definition of Mammal, your optinos are to rewrite everything in the parent, or depend on it.
Many thanks for the answers so far. I've come up with a solution which I think seems reasonable and allows me to fully encapsulate the foreign class.
At the moment I've returned to the method discussed in the first block of code (repeated and extended below) and am now implementing my MyInterface interface for MyNewClass and delegating all interface operations to a composed object. The object to delegate to is decided at runtime by calling a static method on a Factory.
public interface TheirClassInterface {
public void theirMethod1();
public void theirMethod2();
}
public class TheirClass implements TheirClassInterface {
public void theirMethod1() { ... }
public void theirMethod2() { ... }
}
public class TheirOtherClass {
public void theirOtherMethod1(TheirClassInterface o) { ... }
}
public interface MyInterface() {
public void myMethod1();
}
public class MyClass extends TheirClass implements MyInterface {
public void myMethod1() { ... }
}
public class MyNewClass implements MyInterface {
private MyInterface myObject;
public MyNewClass() {
myObject = MyClassFactory.createMyClass();
}
public void myMethod1() {
myObject.myMethod();
}
public void MyNewClassMethod() { ... }
}
Once again, thanks for the ideas. I'm now going to look into them all and see if I can use them to improve my code.
Cheers,
Danny
The java compiler allows me write a Class definition inside an Interface . Are there any specific uses of this ?
interface ClassInterface {
void returnSomething();
int x = 10;
class SomeClass {
private int y;
private void classDoingSomething() {
}
}
}
Please explain .
The uses are the same that a class nested in another class: it allows scoping the class to the interface. You could imagine something like this:
public interface Switch {
public enum Status {
ON, OFF;
}
void doSwitch();
Status getStatus();
}
It avoids defining a top-level class named SwitchStatus (because Status could be a too generic name).
Yes Java allows you to define an inner class inside an interface One use I can think of is tightly binding a certain type (defined by the class) to an interface and perhaps limit access only to the interface methods. There's an example of such use on here
I use that pattern to embed multiple tiny concrete implementations that share a large amount of commonality. It's easier to manage 25 tiny extensions of the same abstract class within the same file. Using like in C# namespace enclosure.
/**
* Dao 道 = access/way/avenue
* Bao 包 = bundle/package/
*/
public interface DaoBao {
public abstract class <E extends BlessedEntity> BlessedDaoWager<E,T> {
private JdbcTemplate jtmpl;
public void setDatasource(Datasource ds) {
this.jtmpl = new JdbcTemplate(ds);
}
public E find(BlessedKey key) {
blah .. blah .. blah ...
}
public List<E> list(Date from, Date to) {
blah .. blah .. blah ...
}
public boolean remove(BlessedKey key) {
blah .. blah .. blah ...
}
public T getKey(E ent) {
return ent.getId();
}
}
public class BlessedEmployeeDao
extends BlessedDaoWager<BlessedEmployeeEntity, Long> {
public Long getKey(BlessedEmployeeEntity ent) {
return ent.getCucurucucu();
}
}
public class BlessedSalaryDao
extends BlessedDaoWager<BlessedSalaryEntity, BlessedEmployeeEntity> {
public BlessedEmployeeEntity getKey(BlessedSalaryEntity ent) {
return ent.getEmployeeId();
}
}
public class BlessedHoursDao
extends BlessedDaoWager<BlessedHoursEntity, BlessedEmployeeEntity> {
public BlessedEmployeeEntity getKey(BlessedSalaryEntity ent) {
return ent.getEID();
}
}
public class BlessedGooDao
extends BlessedDaoWager<BlessedGooEntity, String> {
public String getKey( ent) {
return ent.getName();
}
}
public class BlessedHowDao extends BlessedDaoWager<BlessedEntity, Long> {}
public class BlessedNowDao extends BlessedDaoWager<BlessedEntity, Date> {}
}
There are those who say, what if someone inadvertently implemented the interface. I would say those are inadvertent programmers looking for ways to prevent their inadvertent programming habits.