Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Methods in object-oriented paradigms can be overridden by the methods with same signature in the inheriting classes. Variables however can't. Why?

Wikipedia defines virtual methods as:

In object-oriented programming, a virtual function or a virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature [to provide a polymorphic behavior].

According to the definition, every non-static method in Java is by default virtual except final and private methods. The method which cannot be inherited for polymorphic behavior is not a virtual method.

Static methods in Java can never be overridden; hence, it is meaningless to declare a static method as final in Java because static methods themselves behave just like final methods. They can simply be hidden in sub classes by the methods with the same signature. It is evidently so because static methods can never have polymorphic behavior: a method which is overridden must achieve polymorphism, which is not the case with static methods.

From the preceding paragraph, an important conclusion can be driven. All the methods in C++ are by default static because no methods in C++ can behave polymorphically until and unless they are explicitly declared virtual in the super class. In contrast, all the methods in Java except final, static and private methods are by default virtual because they have polymorphic behavior by default (there's no need to explicitly declare methods as virtual in Java and, consequently, Java has no keyword like "virtual").

Now, let's demonstrate that instance variables (static too) cannot behave polymorphically from the following simple example in Java.

class Super
{
    public int a=5;
    public int show()
    {
        System.out.print("Super method called a = ");
        return a;
    }
}

final class Child extends Super
{
    public int a=6;

    @Override
    public int show()
    {
        System.out.print("Child method called a = ");
        return a;
    }
}

final public class Main
{
    public static void main(String...args)
    {
        Super s = new Child();
        Child c = new Child();

        System.out.println("s.a = "+s.a);
        System.out.println("c.a = "+c.a);        

        System.out.println(s.show());
        System.out.println(c.show());
    }
}

The output produced by the above code snippet is as follows.

s.a = 5
c.a = 6
Child method called a = 6
Child method called a = 6

In this example, both calls s.show() and c.show() made to the show() method through the variables of type Super and of type Child, respectively, invoke the show() method in the Child class. This means that the show() method in the Child class overrides the show() method in the Super class because both of them have the identical signature.

This, however, cannot be applied to the instance variable a declared in both the classes. In this case, s.a would refer to a in the Super class and display 5 and c.a would refer to a in the Child class and display 6 means that a in the Child class just hides (and doesn't override as happened to non-static methods) a in the Super class.

After this long discussion, there is only one question. Why are instance variables (and the rest too) not overridden? What were the special reasons to implement such a mechanism? Would have there been any advantages or disadvantages, if they had been overridden?

like image 927
Lion Avatar asked Dec 28 '11 11:12

Lion


1 Answers

I think that the purpose of overriding is changing functionality without changing the signature. This is relevant for methods only: method may have the same signature but have different behavior. Fields have only "signature" that is also limited to there type and name. They do not have behavior, so nothing can be overridden.

Other reason to inability to "override" fields is that fields are typically private (or should be private), so they are actually the gory details of the class implementation. Methods however represent the external interface of the class. This external interface should support polymorphous to make it easier to change functionality of modules without changing the relationships between modules.

like image 180
AlexR Avatar answered Nov 02 '22 11:11

AlexR