Re: Non-virtual methods - why?
Hi,
[color=blue][color=green][color=darkred]
> > > Java *does* have non-virtual methods (they're called final in Java).
> > > Look at Object.wait() for example.[/color]
> >
> > I think you are wrong. Read the Java Language Specification, para[/color][/color]
8.4.3.3:[color=blue][color=green]
> > "A method can be declared final to prevent subclasses from overriding or
> > hiding it. It is a compile-time error to attempt to override or hide a[/color][/color]
final[color=blue][color=green]
> > method".
> >
> > A final method in Java is close to a sealed method in C# - it prevents
> > further overriding.[/color]
>
> And that, as far as I'm concerned, is the principal feature of being
> non-virtual.[/color]
I don't know how is in JAVA, but if you assert here that declaring a method
as *sealed* si the same as declaring non-virtual method you are wrong. Such
a method is still virtulal.
class A
{
public virtual void f()
{
}
}
class B: A
{
public override void f()
{
}
}
class C: B
{
public override sealed void f();
{
}
}
A a = new C()
a.f() calls C.f()
Isn't it virtual? If it wasn't it would call A.f()
*sealed* modifier force you to stop using overriden until you don't use
*virtual* again and then you can continue override the method. BTW the
compiler generates *callvirt* instruction as a evidence of that the method
is indeed *virtual*
[color=blue][color=green]
> > While in C#, methods can be hidden because they were not marked[/color][/color]
virtual -[color=blue][color=green]
> > so, in order to be sealed a method has to be virtual.[/color]
>
> In my view, they can be sealed to prevent them being virtual any
> further.[/color]
In c# you can keep going with overrideing the method which was sealed. what
you have to is to declared it as virtual again(to start new virtual
implemetation).
That is posible because when CLR decides, which is most-derived method it
doesn't take into account only the runtime type of the object it kind of
takes into account the type of the variable as well.
To be more strict
callvirt is provided with the name of the class from where to start looking
for the most-derived implementation.[color=blue]
>
> My way of looking at things is that something is virtual if it can be
> overridden, and is non-virtual if it can't.[/color]
When you put *sealed* modifier for a method you have to put override as well
(other wise it does'n make sence to prohibit overriding of something which
cannot be overrided anyway). The modifier *override* already means that the
method is virtual.
[color=blue]
> It's all a matter of definition, of course, but mine seems to fit in
> pretty well with this section from the MSDN on virtual members:
>
> <quote>
> The virtual keyword is used to modify a method or property declaration,
> in which case the method or the property is called a virtual member.
> The implementation of a virtual member can be changed by an overriding
> member in a derived class.
>
> When a virtual method is invoked, the run-time type of the object is
> checked for an overriding member. The overriding member in the most
> derived class is called, which might be the original member, if no
> derived class has overridden the member. (For more information on run-
> time type and most derived implementation, see 10.5.3 Virtual methods.)
>
> By default, methods are non-virtual. You cannot override a non-virtual
> method.
> </quote>[/color]
If you read further down the same section you will find example of hiding
virtual methods, which is more closely to what happend when you declare a
method as a *sealed*. *sealed* modifier just force you to hide the method if
you want to change the implementation.
[color=blue]
> Here's another one, from the C# language specification:
>
> <quote>
> The implementation of a non-virtual method is invariant: The
> implementation is the same whether the method is invoked on an instance
> of the class in which it is declared or an instance of a derived class.
> In contrast, the implementation of a virtual method can be superseded
> by derived classes.
> </quote>
>
> A final method in Java absolutely satisfies the descriptions of non-
> virtual methods above. Note that in neither of those two quotes is
> hiding of methods mentioned.[/color]
If *final* in JAVA means that the method cannod be overriden or hid then it
is different form the non-virtual methods.
Non-virtual methods cannot be overriden - OK. One can hide then, though.
So my question is: Why C# allows virtual methods to be hidden. Isn't it
error prone.
I believe that the best is:
1. To have virtual and non-virtual methods.
2. Sealing virtual methods has to prevent further overriding and hiding the
methods.
And actually I think I know the answer. It is side efect of the way the CLR
resolves wich is the most-derived method. .NET is cross langage platform and
if C# was preventing this using calsses written in other languges (allowing
hiding virtual methods) would put C# programmers to consfusion.
B\rgds
100
Hi,
[color=blue][color=green][color=darkred]
> > > Java *does* have non-virtual methods (they're called final in Java).
> > > Look at Object.wait() for example.[/color]
> >
> > I think you are wrong. Read the Java Language Specification, para[/color][/color]
8.4.3.3:[color=blue][color=green]
> > "A method can be declared final to prevent subclasses from overriding or
> > hiding it. It is a compile-time error to attempt to override or hide a[/color][/color]
final[color=blue][color=green]
> > method".
> >
> > A final method in Java is close to a sealed method in C# - it prevents
> > further overriding.[/color]
>
> And that, as far as I'm concerned, is the principal feature of being
> non-virtual.[/color]
I don't know how is in JAVA, but if you assert here that declaring a method
as *sealed* si the same as declaring non-virtual method you are wrong. Such
a method is still virtulal.
class A
{
public virtual void f()
{
}
}
class B: A
{
public override void f()
{
}
}
class C: B
{
public override sealed void f();
{
}
}
A a = new C()
a.f() calls C.f()
Isn't it virtual? If it wasn't it would call A.f()
*sealed* modifier force you to stop using overriden until you don't use
*virtual* again and then you can continue override the method. BTW the
compiler generates *callvirt* instruction as a evidence of that the method
is indeed *virtual*
[color=blue][color=green]
> > While in C#, methods can be hidden because they were not marked[/color][/color]
virtual -[color=blue][color=green]
> > so, in order to be sealed a method has to be virtual.[/color]
>
> In my view, they can be sealed to prevent them being virtual any
> further.[/color]
In c# you can keep going with overrideing the method which was sealed. what
you have to is to declared it as virtual again(to start new virtual
implemetation).
That is posible because when CLR decides, which is most-derived method it
doesn't take into account only the runtime type of the object it kind of
takes into account the type of the variable as well.
To be more strict
callvirt is provided with the name of the class from where to start looking
for the most-derived implementation.[color=blue]
>
> My way of looking at things is that something is virtual if it can be
> overridden, and is non-virtual if it can't.[/color]
When you put *sealed* modifier for a method you have to put override as well
(other wise it does'n make sence to prohibit overriding of something which
cannot be overrided anyway). The modifier *override* already means that the
method is virtual.
[color=blue]
> It's all a matter of definition, of course, but mine seems to fit in
> pretty well with this section from the MSDN on virtual members:
>
> <quote>
> The virtual keyword is used to modify a method or property declaration,
> in which case the method or the property is called a virtual member.
> The implementation of a virtual member can be changed by an overriding
> member in a derived class.
>
> When a virtual method is invoked, the run-time type of the object is
> checked for an overriding member. The overriding member in the most
> derived class is called, which might be the original member, if no
> derived class has overridden the member. (For more information on run-
> time type and most derived implementation, see 10.5.3 Virtual methods.)
>
> By default, methods are non-virtual. You cannot override a non-virtual
> method.
> </quote>[/color]
If you read further down the same section you will find example of hiding
virtual methods, which is more closely to what happend when you declare a
method as a *sealed*. *sealed* modifier just force you to hide the method if
you want to change the implementation.
[color=blue]
> Here's another one, from the C# language specification:
>
> <quote>
> The implementation of a non-virtual method is invariant: The
> implementation is the same whether the method is invoked on an instance
> of the class in which it is declared or an instance of a derived class.
> In contrast, the implementation of a virtual method can be superseded
> by derived classes.
> </quote>
>
> A final method in Java absolutely satisfies the descriptions of non-
> virtual methods above. Note that in neither of those two quotes is
> hiding of methods mentioned.[/color]
If *final* in JAVA means that the method cannod be overriden or hid then it
is different form the non-virtual methods.
Non-virtual methods cannot be overriden - OK. One can hide then, though.
So my question is: Why C# allows virtual methods to be hidden. Isn't it
error prone.
I believe that the best is:
1. To have virtual and non-virtual methods.
2. Sealing virtual methods has to prevent further overriding and hiding the
methods.
And actually I think I know the answer. It is side efect of the way the CLR
resolves wich is the most-derived method. .NET is cross langage platform and
if C# was preventing this using calsses written in other languges (allowing
hiding virtual methods) would put C# programmers to consfusion.
B\rgds
100
Comment