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.
Related
I'm trying to build a base class with a method that needs to call a private method before and after performing the actual logic.
public abstract class Base {
public Base() {}
private void before() {
// doSomething
}
private void after() {
// doSomething
}
public void actual(Object object) {
before();
// doSomething
after();
}
}
public class SomeClass extends Base {
public SomeClass() {}
public void actual(Object object) {
// actual code that needs to be executed between before and after methods.
}
}
How would I go about this?
Create another method that can be overridden and implemented instead of overriding actual directly.
E.g.
public void actual(Object object) {
before();
doActual(object);
after();
}
protected abstract void doActual(Object object);
You could make the actual() method final if you want to ensure that nobody overrides it by mistake.
You can make the method as abstract e.g.
protected abstract void actual(Object object);
and create another public method which is going to be called
public void init(Object object){
before();
actual(object);
after();
}
I'm very new to the java 8 features and try to understand default methods. Is there an easier way to invoke a default method by another default method of the same interface than using an anonymous class?
For example:
public class Frame{
public static void main(String... args){
Frame.C c= new Frame.C();
c.doSomething();
}
public interface A{
public default void doSomething(){
System.out.println("A");
}
}
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
//is there an easier way to invoke that method??
new B(){}.other();
}
default public void other(){
//doSomething();
System.out.println("other");
}
}
public static class C implements B{
#Override
public void other(){
Lambda.B.super.other();
System.out.println("C");
}
}
}
Your intention is not entirely clear, but the construct new B(){}.other(); implies two things:
You don’t want to invoke an overriding method implementation
The instance on which you invoke other() is obviously irrelevant when invoking it on an entirely different instance (new B(){}) is a viable solution
These two things together imply that you should use a static method instead:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
otherInB();
}
default public void other(){
otherInB();
}
static void otherInB() {
//doSomething();
System.out.println("other");
}
}
Since your original method names did not carry useful information, it’s not possible to suggest a useful name for that static method either.
Note that Java 9 is going to introduce support for private methods in interfaces which allows hiding otherInB() to other classes and even making it non-static in case it has to use other methods on the same instance.
If the visibility of the method in Java 8 is an issue, consider that the actual place of a non-polymorphic method is irrelevant, so you can always use a companion class:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other();
}
default public void other(){
BHelper.other();
}
}
…
/* not public */ class BHelper {
/* not public */ static void other() {
//doSomething();
System.out.println("other");
}
}
This even works if the implementation needs the actual B instance as you may pass it as a parameter.
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other(this);
}
default public void other(){
BHelper.other(this);
}
}
…
/* not public */ class BHelper {
/* not public */ static void other(B instance) {
//doSomething();
System.out.println("other");
}
}
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 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().
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.