How to call abstract method from abstract class called by inherit class - java

I want to call a method of an abstract class from abstract class called by inherit class.
Abstract class:
public abstract class Abstract {
protected void updateMotionY(float deltaTime) {
System.out.println("Abstrcat updateMotionY");
}
public void update(float deltaTime) {
this.updateMotionY(deltaTime);
}
}
Inherit class:
public class Obj extends Abstract {
#Override
protected void updateMotionY(float deltaTime) {
System.out.println("updateMotionY");
super.updateMotionY(deltaTime);
}
#Override
public void update(float deltaTime) {
super.update(deltaTime);
}
}
Main method class:
public static void main(String[] args) {
(new Obj()).update(10.0f);
}
Whenever I try to call new Obj().update() method in main class, it prints "updateMotionY" and "Abstrcat updateMotionY". I want to get only "Abstrcat updateMotionY".
Can anyone tell me how to resolve this problem?

I think you are using abstract in a very wrong way. Your base class should rather look like this:
public abstract class Abstract {
protected abstract void updateMotionY(float deltaTime);
public final void update(float deltaTime) {
this.updateMotionY(deltaTime);
}
}
Notes:
there is no point putting print "is abstract" into an abstract method. The java language has a keyword to express this fact.
subclasses should only be about implementing the abstract method(s) (probably in different ways). You absolutely do not want that subclasses change the implementation of other methods of the base class. Your base class defines a contract - and subclasses should adhere to that (as outlined by the Liskov Substitution Principle).
In other words: put the common parts solely in the base class, and make sure that you have to necessary abstract methods in there to do that. But avoid implementing methods more than once. That only leads to confusion and strange bugs.

(new Obj()).update(10.0f) calls Obj::update which calls Abstract::update which calls this.updateMotionY. Because this is an instance of Obj, this calls Obj::updateMotionY.
This prints "updateMotionY".
This then calls super.updateMotionY(deltaTime) which is Abstract::updateMotionY.
This prints "Abstrcat updateMotionY".
That's the end of the call hierarchy and everything unwinds.
Fundamentally your confusion seems to stem from the fact that this.updateMotionY(deltaTime); in the Abstract class resolves to updateMotionY in the Obj class. That's basically the whole point of polymorphism.
One thing you could do is to add a private method (so that it cant be overridden) which contains the actual implementation, and defer to it:
public abstract class Abstract {
private void motionY(float dt)
{
System.out.println("Abstrcat updateMotionY");
}
protected void updateMotionY(float deltaTime) {
motionY(deltaTime);
}
public void update(float deltaTime) {
motionY(deltaTime);
}
}

If you only want to execute the abstracts superclass' method, then the simple solution is to just call super.updateMotionY instead of super.update in your Obj class
public class Obj extends Abstract {
#Override
protected void updateMotionY(float deltaTime) {
System.out.println("updateMotionY: ");
super.updateMotionY(deltaTime);
}
#Override
public void update(float deltaTime) {
super.updateMotionY(deltaTime);
}
}

You cannot create an instance of Abstract class so you're creating an instance of Obj class. Since your requirement is only to call method of Abstract class then why did you override the method updateMotionY
For your requirement this is what you need to do
Abstract class:
public abstract class Abstract {
protected void updateMotionY(float deltaTime) {
System.out.println("Abstrcat updateMotionY");
}
public void update(float deltaTime) {
this.updateMotionY(deltaTime);
}
}
Inherit class:
public class Obj extends Abstract{
/*#Override
protected void updateMotionY(float deltaTime) {
System.out.println("updateMotionY");
super.updateMotionY(deltaTime);
}*/
#Override
public void update(float deltaTime) {
super.update(deltaTime);
}
}
I have commented the overridden code which will give you the required result.
Also, the answer given by https://stackoverflow.com/users/8466177/steven-laan will also work.

Related

java interface method removing from subclass

Anyone provide suggestion for below mentioned:
in java8 consider an interface having two methods (eg interface1 ,interface 2)
implementing those to many subclass later i want to remove one method interface1 from one of my subclass without affecting other is any possible solution is there?
If your subclass declares that it implements this interface, then you have no choice but to provide implementations for all methods, or declare the class abstract. If you want a concrete class which however does not functionally implement all methods in the interface, then here is one option:
public interface YourInterface {
void method1();
void method2();
}
public class YourSubClass implements YourInterface {
#Override
public void method1() {
// actually do something
}
#Override
public void method2() {
throw new UnsupportedOperationException("method2() is not supported here.");
}
}
Here while we do implement all methods, we throw a runtime exception should a caller try to access method2().
You can do this by providing a default method implementation for the interface1 method in the interface itself.
interface Interface {
default void interface1() {
System.out.println("interface1");
}
void interface2();
}
class Clazz implements Interface {
#Override
public void interface2() {
System.out.println("interface2");
}
}
Depends how you define 'remove one method'.
If you have interface
interface Interface{
void interface1();
void interface2();
}
And for example two subclasses that extend it:
class Class1 implementes Interface {
#Override
public void interface1(){ ... }
#Override
public void interface2(){ ... }
}
class Class2 implementes Interface {
#Override
public void interface1(){ ... }
#Override
public void interface2(){ ... }
}
Then there are two scenarios:
You don't want to implement for example interface1() method in Class2:
You don't want to have interface1() method in Class2
In case of 1. as Robby Cornelissen mentioned, you can simply provide default implementation in Interface:
default void interface1() { /*do default thing*/ }
In case of 2. you need to remove the interface1() method from the Interface.
You can do that by simple moving definition of method interface1() to Class1 (and any other sublass that needs to have it). but that is not really generic approach.
Best is to extract for example Interface1 with method interface1() and use that interface in classes that need to have that method. You will end up with this situation:
interface Interface{
void interface2();
}
interface Interface1{
void interface2();
}
And for example two subclasses that extend it:
class Class1 implementes Interface, Interface1 {
#Override
public void interface1(){ ... }
#Override
public void interface2(){ ... }
}
class Class2 implementes Interface {
#Override
public void interface2(){ ... }
}

How to create a java method on a base class that calls other methods?

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();
}

Could we call super.someMethod() in derived class from an abstract class?

Could we call super.someMethod() in derived class from an abstract class?
for in stance:
abstarct class TestBase{
void nonabstractMethod(){
....
}
}
Then derived class:
class Child extend TestBase{
void callFunction(){
}
void nonabstractMethos(){
super.nonabstractMethos();
}
}
I assume this can be done. But if we have an abstract method then it cannot be called because of no implementation, am i correct?
The short answer: yes.
You can always call a public or protected super method. Like any (instance) method in java, it will be handled polimorphicly, and a concrete implementation will be called, either of the super's class or from the derived class if it overrides it.
Yes you are correct. If you are extending an abstract class having abstract method, you can't call super.thatMethod();
Consider the following example
public class RSAService {
protected void doRSA(){}
}
class MyService extends RSAService{
public void myService(){
super.doRSA(); //Works fine
}
}
This will work as the doRSA() is accessible from the MyService. Same for public but not for private
But
public abstract class RSAService {
protected abstract void doRSA();
}
class MyServe extends RSAService{
public void myService(){
super.doRSA(); //This won't work
}
#Override
protected void doRSA() {
}
}
Now consider this case, where you can call the super.superClassMethod() from your subclass
public abstract class RSAService {
protected void doRSA(){}
}
class MyService extends RSAService{
public void myService(){
}
#Override
protected void doRSA() {
super.doRSA();
}
}
So if you are overriding a super class method you can call the method using super. Consider this Java Specification link for more clarification
Your example will work if both classes are in the same package.
If that is not the case, then you should declare the method protected or public, something like:
abstract class TestBase{
protected void nonabstractMethod(){
....
}
}
If your method is abstract, then you can't call it, for example:
abstract protected void abstractMethod();

Can't cope with inheritance

I have (some pseudocode):
public class Thrd extends Thread{
protected void letUsFinalize(){
int a = 0; // Just for debugging.
}
}
public class FreeThread extends Thrd{
#Override
protected void letUsFinalize() {
FreeThread.this.interrupt();
}
}
Please, have a look at the picture. Our object now is of class FreeThread (visible in the Variables subsection). So, I come to the upper break point in the picture, press Step into and I occur at the lower break point. I mean that I occur in the method of the class Thrd (superclass).
What should I do so that the method of subclass would execute in this case?
If the object that you are using is an instance of FreeThread, then calling object.letUsFinalise() will call the method from FreeThread.
It looks like you are calling letUsFinalise() from the super class, so it's not possible to call the subclass' method unless you are using a static object to it (demonstrated below).
public class SuperClass {
public void method(){
Objects.object.method();
}
}
class SubClass extends SuperClass{
#Override
public void method(){
System.out.println("I'm the sub class!");
}
}
class Objects{
public static SubClass object = new SubClass();
}
I suggest that you create a static object of FreeThread and use that to call the method, as shown above.

Overwriting methods: how to "inject" into the super-method?

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.

Categories