I am having issue with calling a method of a class at the 2nd level of inheritance from the super class.
The scenario is this,
abstract class SuperClass
{
public void MethodOne()
{
MethodTwo();
}
public abstract void MethodTwo();
}
class Sub1 extends SuperClass
{
public void MethodTwo()
{
//code in sub1
}
}
class Sub2 extends SuperClass
{
public void MethodTwo()
{
//code in sub2
}
}
With the below code I expect the MethodTwo() from the Sub2 to be called. But the method from Sub1 is getting called. Am I missing something?
SuperClass anObj = new Sub2();
anObj.MethodOne();
I have combined all of your classes as inner-classes to help me test them. You can remove the "static" keyword from the classes if you put them in different files:
public class Example {
abstract static class SuperClass
{
public void MethodOne()
{
MethodTwo();
}
public abstract void MethodTwo();
}
static class Sub1 extends SuperClass
{
#Override
public void MethodTwo()
{
System.out.println("Sub1.MethodTwo()");
}
}
static class Sub2 extends SuperClass
{
#Override
public void MethodTwo()
{
System.out.println("Sub2.MethodTwo()");
}
}
public static void main(String[] args) {
SuperClass anObj = new Sub2();
anObj.MethodOne();
}
}
When I run this class it outputs Sub2.MethodTwo(), proving that it does actually work as you expect.
I notice the code you provided is not proper java code, and does not compile. That's because you've marked methods both as abstract and then provided an implementation with curly-braces { ... }.
I assume this is an example of a setup that isn't working for you? If so, I think it doesn't represent your case properly - as it's working as one would expect!
First, you lack the actual implementation of method2.
You should not be able to call an abstract method.
You need to override the abstract in the subclass.
class Sub1 extends SuperClass
{
#override
public void MethodTwo()
{
//code in sub1
}
}
class Sub2 extends SuperClass
{
#override
public void MethodTwo()
{
//code in sub2
}
}
This might fix your problem.
Related
How to use a non-abstract method from an abstract class in another class without extending?
Abstract Class:
package com.test;
public abstract class MyAbstract {
public abstract void abstractMethod();
public void callNonAbstractMethod() {
System.out.println("Hello");
}
}
The anonymous class:
package com.test;
public class Example {
public static void main(String[] args) {
new Example().something();
}
void something() {
MyAbstract a = new MyAbstract() {
#Override
public void abstractMethod() {
//TODO implement
}
};
a.callNonAbstractMethod();
}
}
Internal class generated by the compiler would be for above example.
static class Example extends MyAbstract
{
Example(){}
void abstractMethod()
{
System.out.println("hiee");
}
}
Abstract Class:
package com.test;
public abstract class MyAbstract {
public abstract void abstractMethod();
public void callNonAbstractMethod() {
System.out.println("Hello");
}
}
You can't.
To call any non-static method of some class A, you need an instance of A or of a subclass of A, as such a method typically operates on data within such an instance. That's at the very core of what "object-oriented" is all about.
In your case, A is abstract and can't have direct instances. So the only way to call your method is to have some instance of some class B that extends A. You can either find an existing subclass that you can use, or create your own subclass.
I think you can use an anonymous class. Although it is a kind of extension, you are not explicitly using the keyword extends. In fact, you cannot use any class in java without implicitly extending because every class extends Object.
package com.test;
public class Example {
public static void main(String[] args) {
new Example().something();
}
void something() {
MyAbstract a = new MyAbstract() {
#Override
public void abstractMethod() {
//TODO implement
}
};
a.callNonAbstractMethod();
}
}
and here's your abstract class:
package com.test;
public abstract class MyAbstract {
public abstract void abstractMethod();
public void callNonAbstractMethod() {
System.out.println("Hello");
}
}
results in:
Hello
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.
What would be the best way to achieve testCall2 below without doing explicit parsing (Sub1) in?
class Super {
}
class Sub1 extends Super {
}
class Sub2 extends Super {
}
public void testCall2(Super in) {
testCall(in); // <~~~ Compilation Error
}
public void testCall(Sub1 sub) {
}
public void testCall(Sub2 sub) {
}
You'd have to refactor and use polymorphism. Declare the testCall method in Super
class Super {
public void testCall() {}
}
and implement it in the subclasses.
Then invoke it
public void testCall2(Super in) {
in.testCall();
}
Otherwise you'll have to use a cast to transform the value's type to a type expected by either of the methods.
Obviously it will give compile time error because you are creating methods out of class body. your all methods are out of class body..
class Super {
}
class Sub1 extends Super {
}
class Sub2 extends Super {
}// your all three classes are started and ended immediately
public void testCall2(Super in) {
testCall(in); // <~~~ Compilation Error
}
public void testCall(Sub1 sub) {
}
public void testCall(Sub2 sub) {
}
//and all three methods are defined out of any class body.
I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().
Assuming three classes, one being a subclass of the other. Each overwrite the parents' method.
public class BaseClass {
public void doStuff() {
performBaseTasks();
}
}
public class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
super.doStuff();
}
}
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
performFinalTasks();
super.doStuff();
}
}
When calling new FinalClass().doStuff(), this would lead to a method
invokation order as follows:
performFinalTasks();
performMiddleTasks();
performBaseTasks();
I want to bring the perfomFinalTasks() between performMiddleTasks() and
performBaseTasks(). How can I do this?
performMiddleTasks();
performFinalTasks();
performBaseTasks();
Write a public method in final class doStuffDifferently() and invoke these methods in that order. I am not sure it's possible to do it via any other tricks in the doStuff() method.
One possible way, if you can make the middle class abstract:
public abstract class MiddleClass extends BaseClass {
// {BaseClass} Overrides
public void doStuff() {
performMiddleTasks();
doProxyExec();
super.doStuff();
}
public abstract void doProxyExec();
}
You override the proxy method in your subclass:
public class FinalClass extends MiddleClass {
// {BaseClass} Overrides
public void doStuff() {
super.doStuff();
}
// {MiddleClass} Overrides
public void doProxyExec(
performFinalTasks();
}
}
A not very polymorphic way of method call chaining, but then again the original design is kind of ... odd.