I'm trying to realize an ADT for one of my programs, and I'm having difficulty implementing it correctly for use without error. Here is some sample code I'm working with:
//JavaApplication
package javaApplication;
import someADT.*;
public class JavaApplication {
public JavaApplication () {
abstractType a = new typeFor("Hello"); //Err1
}
public abstract class typeFor implements abstractType { //Err2
public abstractType typeFor (String s) {
//some code
}
}
public static void main(String[] args) {
JavaApplication j = new JavaApplication();
}
}
Below is the list of accessor methods.
//abstractType implementation
package someADT;
public interface abstractType {
public abstractType doSomethingA();
public abstractType doSomethingB(abstractType a);
public int doSomethingC(abstractType a);
}
I'm not entirely sure how to implement abstract types which should be obvious. I've commented some of the lines above with errors, which are:
Err1 = is abstract and cannot be instantiated
Err2 = attempting to assign weaker access privileges
I'm very new to this, but I can't find solid documentation on how to do it properly. I have lecture slides but I'll admit they're fairly barebones. I did use the example provided and just swapped my own stuff but kept the general syntax and I get these errors.
What is wrong with my implementation?
You are missing few things here:
You can not instantiate an abstract class in Java
A non-abstract class should implement all the abstract methods it inherits from a super class/interface
Constructors can not have return type
an abstract class canNOT extend an INTERFACE. It can only implement it. An interface cannot be instantiated. It can only be implemented by other classes or extended by other INTERFACES.
You could improve your code by doing the following:
public class JavaApplication {
public JavaApplication () {
abstractType a = (new typeFor()).typeFor("HELLO"); //Err1
}
public class typeFor implements abstractType { //Err2
public abstractType typeFor (String s) {
return null;
}
#Override
public abstractType doSomethingA() {
// TODO Auto-generated method stub
return null;
}
#Override
public abstractType doSomethingB(abstractType a) {
// TODO Auto-generated method stub
return null;
}
#Override
public int doSomethingC(abstractType a) {
// TODO Auto-generated method stub
return 0;
}
}
public static void main(String[] args) {
JavaApplication j = new JavaApplication();
}
}
Related
When we implement multiple iheritance for the class RunExample it is running fine without any issues or errors at compile time or runtime. How does jvm knows which method to implement when same methods are declared in different interfaces?
package InterfaceSegregation;
public interface A {
public void work();
public void takeBreak();
}
package InterfaceSegregation;
public interface B {
public void takeBreak();
}
package InterfaceSegregation;
public class RunExample implements A,B{
public static void main(String[] args){
RunExample e = new RunExample();
System.out.println(e instanceof A);
System.out.println(e instanceof B);
}
#Override
public void work() {
// TODO Auto-generated method stub
}
#Override
public void takeBreak() {
}
}
Basically implementing an interface is a means of controlling what methods will the object have. As long as the signature including return type is the same java will allow it.
Check the Oracle docs.
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.
For a project I want to provide a generic interface to resemble a workflow, like
public interface IWorkflow
{
public void start();
public void doWork();
public void end();
}
For that, I have lots of implementation, like
public class CoffeeWorkflow implements IWorkflow
{
public void start()
{
// setup coffee
// prepare dishes
// ...
}
public void doWork()
{
// drink coffee
}
public void end()
{
// wash dishes
}
}
Now I want to provide more information to those functions, like
public interface IWorkflowStartArgs
{}
And especially:
public class CoffeeWorkflowStartArgs implements IWorkflowArgs
To give it into the method
public interface IWorkflow
{
public void start(IWorkflowStartArgs args);
public void doWork();
public void end();
}
respectivly:
public class CoffeeWorkflow implements IWorkflow
{
public void start(CoffeeWorkflowStartArgs args)
{
}
}
But this does not work, as it is not recognized as implementation
of the interface.
Should I pass in an IWorkflowStartArgs and cast it inside?
Is there a better solution to that?
You can define interface like
interface IWorkflow<T extends IWorkflowStartArgs>
{
public void start(T args);
public void doWork();
public void end();
}
and when you create CoffeeWorkflow you can create something like
class CoffeeWorkflow implements IWorkflow<CoffeeWorkflowStartArgs>
{
#Override
public void start(CoffeeWorkflowStartArgs args) {
// TODO Auto-generated method stub
}
#Override
public void doWork() {
// TODO Auto-generated method stub
}
#Override
public void end() {
// TODO Auto-generated method stub
}
}
Java won't consider it as the specific implementation type.
Consider the following case, where you can see where the problem will occur (IF automatic mapping of implemented class in the function argument is seen valid by Java):
public class CoffeeWorkflow implements IWorkflow
{
public void start(IWorkflowStartArgs args)
{
// This is what Java sees as actual implementation
}
public void start(CoffeeWorkflowStartArgs args)
{
// This is yet again SEPARATE method with different signature
// In case of auto-casting (if there would have been), this method would be AMBIGUOUS
}
}
The solution?
Well use Generics as illustrated by #sanbhat
Or if you don't want to go into Generics,
Then I think you should pass in an IWorkflowStartArgs and cast it inside as you said first,
like this way:
public class CoffeeWorkflow implements IWorkflow
{
public void start(IWorkflowStartArgs args)
{
if (args instanceof CoffeeWorkflowStartArgs) {
CoffeeWorkflowStartArgs coffeeArgs = (CoffeeWorkflowStartArgs) args;
// ....
}
}
// ....
}
Suppose you have another similar class TeaWorkFlow,
then again you need to check instanceof.
This is why Generics were mainly introduced - To avoid repeatedly checking by instanceof;
And to serve as a general model for similar pattern classes.
There is a solution using a single generic parameter, that ensures type safety. Lets use the generic parameter WorkflowType for it:
interface IWorkflow<T extends WorkflowType>
{
public void start(IWorkflowStartArgs<T> args);
public void doWork(IWorkflowWorkArgs<T> args);
public void end(IWorkflowEndArgs<T> args);
}
You can now instantiate your generic parameter:
public class CoffeeWorkflowType extends WorkflowType {
}
Your CoffeeWorkflow looks like this:
public class Coffee implements IWorkflow<CoffeeWorkflowType> {
{
public void start(IWorkflowStartArgs<CoffeeWorkflowType> args);
public void doWork(IWorkflowWorkArgs<CoffeeWorkflowType> args);
public void end(IWorkflowEndArgs<CoffeeWorkflowType> args);
}
and the implementations for your workflow arguments:
public class CoffeeWorkflowStartArgs implements IWorkflowStartArgs<CoffeeWorkflowType> { ... }
public class CoffeeWorkflowWorkArgs implements IWorkflowWorkArgs<CoffeeWorkflowType> { ... }
public class CoffeeWorkflowEndArgs implements IWorkflowEndArgs<CoffeeWorkflowType> { ... }
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
Here is a Java question
How can I implement the inner class's interface in outer class?
I try the following, but in vain. Thank You
class A implements interface B.C{
static class B{
interface C{
}
}
}
I would do like this :
Assuming both the classes are in same package with proper imports.
public class Nestedinterface {
public interface NestI{
void show();
}
}
public class NestedinterfaceImpl implements NestI {
public static void main(String a[]) {
NestI n = new NestedinterfaceImpl();
n.show();
}
public void show() {
// TODO Auto-generated method stub
System.out.println("Hello world");
}
}