C # and Java Overrides Story

By chance, I reexamined the C # and Java override specifications and the behavior of the new modifier specific to C # (and C ++), so I will post it. Please note that the author has moved from C # to Java (Android) and is writing from the Java side.

Conclusion first

  1. In principle all methods ** cannot be overridden **
  2. When overriding, use the virtual modifier and the override modifier in pairs
  3. Overrides are class "extensions" and new modifiers are class member "hidden", paired concepts
  1. In principle, all methods can be ** overridden ** (except when declared final)
  2. If you want to override, just add the Override annotation
  3. No new modifier (new operator only)

Let's look at each one.

1. Is it possible to override in principle? impossible?

It seems that this difference between C # and Java comes from the design concept. The next quote is about C ++, but it seems that it has been carried over to C #.

In C ++, virtual functions generally have the disadvantage of worse performance than regular member function calls because it is not possible to determine which member function to call at compile time. As a result, performance-conscious C ++ programmers are very reluctant to add virtual modifiers to class member functions that do not need to be inherited. [wiki: Method (Computer Science)](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89_(%E8%) A8% 88% E7% AE% 97% E6% A9% 9F% E7% A7% 91% E5% AD% A6))

for,

Java is virtual by default [wiki: Method (Computer Science)](https://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89_(%E8%) A8% 88% E7% AE% 97% E6% A9% 9F% E7% A7% 91% E5% AD% A6))

So all methods are overridable by default. Note that "virtual" refers to a member with the virtual modifier in C #, and indicates that it can be overridden (details in the next section).

2. Comparison of how to write overrides

For C

In principle, overriding is not possible in C #, so there are the following restrictions when overriding.

  1. Overridden methods require ** virtual modifier **
  2. Requires ** override modifier ** when overriding in derived class

The notation is as follows.

class Parent {
    //Overridden method
    public virtual void Hoge() {...}
}

class Child : Parent { //Inherit Parent
    public override void Hoge() {...} //override
}

For Java

On the other hand, Java can be overridden in principle, so do nothing to the overridden method and add the Override annotation on the derived class side to override it.

class Parent {
    //Overridden method
    public void hoge() {...}
}

class Child extends Parent { //Inherit Parent
    //Override with Override annotation
    @Override
    public void hoge() {...}
}

3. What is the new modifier

Now, with that in mind, let's take a look at the C # reference.

new and override have contradictory meanings, so using these two modifiers on the same member will result in an error. The new modifier creates a new member with the same name and hides the original member. The override modifier extends the implementation of inherited members. new modifier (C # reference)

Unlike the override, the new modifier hides the base member [^ 1], but let's actually run the console program and check it.

class Program {
    static void Main(string[] args) {
        Parent parent = new Parent();
        Child child = new Child();
        Parent childInParent = new Child(); //The behavior of this guy changes

                                        //output
        parent.Hoge();                  //Parent#Hoge()
        parent.VirtualMethod();         //Parent#VirtualMethod()

        child.Hoge();                   //Child#Hoge()
        child.VirtualMethod();          //Child#VirtualMethod()

        childInParent.Hoge();           //Parent#Hoge()← Parent outputs (* 1)
        childInParent.VirtualMethod();  //Child#VirtualMethod()

        Console.ReadLine();
    }
}

public class Parent {
    public void Hoge() {
        Console.WriteLine("Parent#Hoge()");
    }

    //The virtual and override modifiers are a pair (* 3)
    public virtual void VirtualMethod() {
        Console.WriteLine("Parent#VirtualMethod()");
    }
}

public class Child : Parent {
    //Hide with new modifier (* 2)
    public new void Hoge() {
        Console.WriteLine("Child#Hoge()");
    }

    //Override (* 3)
    public override void VirtualMethod() {
        Console.WriteLine("Child#VirtualMethod()");
    }
}

All C # methods are non-virtual methods, so ** the type of variable determines which class of method to call *. In the above code, I want to call Child # Hoge () because the childInParent variable is assigning an object of type Child, but because the variable is of type Parent, Parent # Hoge () is called. It's gone ( 1).

On the other hand, the Child type variable child outputsChild # Hoge ()when calling Hoge (). It sounds obvious, but this indicates that Parent # Hoge () was ** hidden ** by the method Child # Hoge () of the same name (* 2).

Also, when overriding, add the virtual modifier to make it a virtual method, and implement it with the override modifier in the derived class (* 3).

Summary

I've written the conclusions earlier, so there's no summary, but you might be wondering why Java Swamp has a feature that looks a lot like this override. I think the advantages of C # from Java's point of view are as follows.

  1. Prevent performance degradation due to virtualization
  2. Explicitly indicate overridable methods

If there are any mistakes, we will correct them. I would be grateful if you could tell me the advantages. Thank you for reading.

[^ 1]: Properties, field members, etc. can also be virtualized, but omitted because the method seems to be the most used

Recommended Posts

C # and Java Overrides Story
[Java] HashCode and equals overrides
Encrypt with Java and decrypt with C #
[Java] What are overrides and overloads?
Java static story
java core: HotSpot compiler and C heap
Link Java and C ++ code with SWIG
Java and JavaScript
XXE and Java
Java Direction in C ++ Design and Evolution
Java initializer story
Java to C and C to Java in Android Studio
Java generic story
Differences in writing Java, C # and Javascript classes
Summarize the differences between C # and Java writing
Getters and setters (Java)
[Java] Thread and Runnable
Java true and false
[Java] String comparison and && and ||
Java --Serialization and Deserialization
[Java] Arguments and parameters
Lombok's Java 9+ support story
[Java] Branch and repeat
[Java] Variables and types
java (classes and instances)
[Java] Overload and override
Organize builds in C ++ / Java and Win / Linux combinations
Java language from the perspective of Kotlin and C #
Study Java # 2 (\ mark and operator)
Java version 8 and later features
[Java] Aizu Online Judge's story 2
[Java] Aizu Online Judge's story 1
Solving in Ruby, Perl and Java AtCoder ABC 113 C Reference
[Java] Difference between == and equals
[Java] Stack area and static area
[Java] Generics classes and generics methods
Java programming (variables and data)
Java encryption and decryption PDF
Fastest Primality Test C # Java C ++
Java class definition and instantiation
[Java] About String and StringBuilder
Kotlin post- and pre-increment and operator overload (comparison with C, Java, C ++)
Ruby C extension and volatile
☾ Java / Iterative statement and iterative control statement
Advantages and disadvantages of Java
java (conditional branching and repetition)
Reproduce Java enum in C #
About Java Packages and imports
Java abstract methods and classes
Java while and for statements
Java encapsulation and getters and setters
Solving with Ruby, Perl and Java AtCoder ABC 129 C (Part 1)
AtCoder ARC 081 C hash to solve in Ruby, Perl and Java
About C # lambda expressions and Linq
About Java static and non-static methods
C # cheat sheet for Java engineers
C, Java, JDBC, JSP, Applet tutorials
I compared PHP and Java constructors
Use java with MSYS and Cygwin
Distributed tracing with OpenCensus and Java
[Java] Difference between Hashmap and HashTable