Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

abstract methods and overiding function in C++ and Java

In C++ and Java, or their respecting rules, what limits are placed on overiding abstract methods. Must you match the arguments or return type. I usually see abstract functions implemented with only a return type and no arguments, is it up to derived class to specify the rest. How does it work exactly?

like image 787
rubixibuc Avatar asked Aug 10 '26 12:08

rubixibuc


1 Answers

Method overriding must have the same method signature of the parent method it's overriding, otherwise it's not called overriding.

Java:

public abstract class AbstractTest {

    public abstract void test() throws Exception;
}

public class ConcreteTest extends AbstractTest {

    @Override
    public void test() throws Exception {

    }
}

As you can see, ConcreteTest (which extends AbstractTest) must override test(). They have the same method name, return types and no method parameters. The subclass can omit the exceptions thrown from the base class and throw its own Exception. The subclass can also add additional (un)checked exception.

As Peter Lawrey mentioned, a java interface methods are implicitly abstract method (See my SO question on Java Abstract Interface).

What is crucial here is that the method visibility cannot change in this case (as it's a hierarchical visibility, i.e. private->protected->public). This is valid though:

public abstract class AbstractTest {

    protected abstract void test() throws Exception;
}

public class ConcreteTest extends AbstractTest {

    @Override
    public void test() throws Exception {

    }
}

(The parent has a protected method and the subclass can override the same method and only has 2 choice for visibility: protected or public).

Also, Suppose you have

public class B {

}

public class D extends B {

}

public abstract class Base {

    public abstract B foo();
}

public class Derived extends Base {

    @Override
    public D foo() {
        // TODO Auto-generated method stub
        return new D();
    }

}

You will see that Derived returns a D and not a B. Why is that? That's because the derived class follows the same signature as the parent class and the return type of the derived class is a subtype of the return type of the parent class.

So, I can have this:

Base pureBase = new Derived();
B b = pureBase.foo(); //which returns class D

if (b instanceof D) {
   //sure, it is, do some other logic
}

In C++, you can get similar effect, using Covariant Return types

C++

class AbstractTest {
public:
    virtual void test() = 0;
};


class ConcreteTest : AbstractTest {
public:
    void test() {
        //Implementation here...
    }
};

In C++, a class with a pure virtual function (a virtual function that ends with a =0) is known as an Abstract class. The subclass (in C++, class extension is delimited by :) override the pure virtual method (except it doesn't contain the =0). It has the same signature has its parent class.

Going back to our Java example, suppose you have:

class B {

};

class D : B {

};

class Base {
public:
    virtual B* foo() = 0;
}

class Derived : Base {
public:
    D* foo() {
        return new D();
    }
}

The same reasoning (as explained in java) is done here. Covariant return types also works with protected and private inheritance. More on Covariant return types.

like image 104
Buhake Sindi Avatar answered Aug 13 '26 00:08

Buhake Sindi