0
public class Main {
    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.x); // 10 is printed
        System.out.println(p.print()); // Child is printed
    }
}

class Parent{

    int x = 10;
    public String print(){ return "Parent";}
}

class Child extends Parent{

    int x = 55;

    public String print(){ return "Child"; }
}

Why Dynamic Method Dispatch is not working on properties ? Is there any purpose, meaning or it was just designed like that.

Hovo
  • 3
  • 2
  • 1
    why "... _method_ ..." is not working for fields. you have an obvious contradiction already in the question – Eugene Jul 27 '21 at 02:03
  • Yes :) it's method dispatch :) ok why there is not any Dynamic Property Dispatch ? – Hovo Jul 27 '21 at 02:05
  • I honestly don't know the technical reasons for this, but it is a fact. fields do not work like that. – Eugene Jul 27 '21 at 02:08
  • [here](https://stackoverflow.com/a/41527570/1059372) is actually a decent answer that looks into the JLS, but it does not mention the _why_ part. – Eugene Jul 27 '21 at 02:10
  • I believe that `x` does not override the parent class, it hides it. That may seem a distinction without a difference, but it's what I got. Because `x` is not overridden, you get the definition according to the static type, which you declare as `Parent`. – markspace Jul 27 '21 at 02:14
  • This is hard to write an answer for why this is, because the idea of overriding a variable seems very vague, that makes reasoning about it hard. Already shadowing accomplishes giving the subclass its own copy of the variable, what do you accomplish by overriding? It seems like all it would allow is making it easier for subclasses to break things. – Nathan Hughes Jul 27 '21 at 02:25
  • Also please don’t use ambiguous wording. Java doesn’t have actual properties as a language level feature, and this question doesn’t seem to be about Javabeans properties, so it seems misleading to use this term. – Nathan Hughes Jul 27 '21 at 02:29
  • Method arguments don't get dynamic dispatch as well, thus the Visitor pattern. It is what it is - a downside of the Java static type system that needs workarounds. – mlntdrv Aug 04 '23 at 13:44

2 Answers2

0

Effectively? Because unlike methods, fields cannot be overridden. Fundamentally: It makes no sense.

When you override a method, it is not about just the name. Only if everything matches, does it count. Let's try this:

public class Example {
    @Override public boolean equals(Example other) { return false; }
}

The above will not compile because that is not the same as Object's own equals. The parameter type doesn't match. As a language syntax sugar nicety to you, you may 'widen' your specs (you can specify a more specific return type, and a more general parameter type, and you can elect to declare fewer checked exceptions), but if you inspect a class file, you'll find the exact method signature of your parent class in your own.

Expanding that notion to fields, a field isn't just the name. It's the name and its type.

When you declare int x; in class Parent, that field exists in all instances of Parent, including any instances of a subclass of Parent. In other words, your class Child extends Parent class already has an x field. There's nothing you can do to change its essence. That's in sharp contrast to methods, where you can redefine what it does by changing the code. This just doesn't apply to fields: Fields don't have code.

Because of all that, when you declare a method that has the same signature as a method declaration of a parent, that is an override, but:

When you declare a field that has the same signature (same name, same type) as a parent class's field, you are declaring a second, separate field whose name shadows the field of the parent.

The behaviour is just completely different. The simple solution is to simply not declare int x, at all, in child. Write into parent's x, if you must. The above explains why this behaviour is so very different.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
0

Writing classes that participate in an inheritance hierarchy is hard. We need the classes to expose behavior and allow customization by subclasses, but without allowing subclasses to change things the superclass is counting on. Allowing subclasses to override methods, but keeping superclass state private accomplishes this separation.

However, if subclasses can override variables in a superclass then the superclass can’t have confidence in the variables it needs to manipulate and the subclasses can tamper with the superclass. The superclass may work or not, depending on what extends it.

If this was a feature, and you had the option to use it or not, similar to using a keyword like virtual in C# but for methods, when would you use it? I can’t think of a case where it would make sense.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276