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.
Let's look at each one.
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).
In principle, overriding is not possible in C #, so there are the following restrictions when overriding.
The notation is as follows.
class Parent {
//Overridden method
public virtual void Hoge() {...}
}
class Child : Parent { //Inherit Parent
public override void Hoge() {...} //override
}
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() {...}
}
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).
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.
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