Non-virtual methods - why?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • 100

    #16
    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



    Comment

    • Adrian Herscu

      #17
      Re: Non-virtual methods - why?


      "Horatiu Ripa" <unreal@busines sco.us> wrote in message
      news:e8pws8$gDH A.1008@TK2MSFTN GP12.phx.gbl...[color=blue]
      > I can't give you a good explanation of that. Especially because you can
      > "overwrite" a method even if it is not declared virtual in the base class
      > (by declaring a method with the same name an params in the child with[/color]
      "new")[color=blue]
      > and having the same behaviour. Probably the binding mechanisms take some
      > advantages of it, but it is just a supposition, I didn't explore this[/color]
      issue.[color=blue]
      > Another questions is "why not?". Anyhow I find it good as long as the code
      > is more readable and understandable, when you see the "override" keyword[/color]
      in[color=blue]
      > a method decalaration it is clear that it overrides/implements a method of[/color]
      a[color=blue]
      > base class.
      >[/color]

      I've already explained what's the difference between "overriding " and
      "hidding",
      and it is not superficial.
      [color=blue]
      >
      > Where?
      > 1. In polymorphic structures, where the base class contains some common
      > behaviour/property that is the same for the derrived classes i.e.:
      > - shape (base) with circle, square, triangle (derrived): a setColor()[/color]
      method[color=blue]
      > is the same for all the shapes
      >[/color]

      OK - some "setColor(int32 )" method is implemented the same across the
      derivation tree.
      So what? What advantage I'm gaining by implementing this method as
      non-virtual?
      The only advantage I can see, is some increased performance (because the
      call goes
      direcly to the method implementation and not through a v-table).
      And by the way, a typical implementation of "setColor(int32 )" will probably
      look like:
      this.color = iColor; hardly an algorithm, so it couldn't be expected to
      change much
      across the derivation tree anyway.
      [color=blue]
      >
      > 2. In classes that contains general behaviours, when you want the derrived
      > classes only to extend the behaviours and not to change any of the base
      > behaviours i.e.:
      > - humanBeing (base) that contains goToSleep(), awake(), walk(), jump(),
      > stay(); women derrived from humanBeing that contains talkTooMuch(),
      > spendMensIncome () and man that contains watchAllSportAt TV(),
      > seekOtherWomen( ) and so on... :))
      >[/color]

      I'm not sure about this example as well. A human being does "goToSleep( )",
      but
      men and women can do it differently - a men will go to sleep without
      brushing his teeth.
      [color=blue]
      >
      > Anyhow you can do that explicitly by marking the methods as "sealed", and[/color]
      ,[color=blue]
      > as I already wrote, you can trick that.
      >[/color]

      As I've already said, "sealed" methods can still be hidden (unlike Java's
      "final") -
      so a "sealed" method is just a non-virtual method.
      [color=blue]
      >
      > --
      > Horatiu Ripa
      > Software Development Manager
      > Business Logic Systems LTD
      > 21 Victor Babes str., 1st floor, 3400 Cluj-Napoca, Romania
      > Phone/Fax: +40 264 590703
      > Web: www.businesslogic.co.uk
      >
      > This email (email message and any attachments) is strictly confidential,
      > possibly privileged and is intended solely for the person or organization[/color]
      to[color=blue]
      > whom it is addressed. If you are not the intended recipient, you must not
      > copy, distribute or take any action in reliance on it. If you have[/color]
      received[color=blue]
      > this email in error, please inform the sender immediately before deleting
      > it. Business Logic Systems Ltd accepts no responsibility for any advice,
      > opinion, conclusion or other information contained in this email or[/color]
      arising[color=blue]
      > from its disclosure.
      >
      > "Adrian Herscu" <bmf1972@hotmai l.com> wrote in message
      > news:ewIpfn7gDH A.632@TK2MSFTNG P10.phx.gbl...[color=green]
      > > That's interesting - other examples?
      > >
      > > "andrew queisser" <andrew.queisse r@hp.com> wrote in message
      > > news:3f73198f$1 @usenet01.boi.h p.com...[color=darkred]
      > > > One common use is with the "Template Method" pattern:
      > > > the base class declares a public non-virtual function which
      > > > checks preconditions, calls a protected or private virtual
      > > > function, then checks postconditions, like so:
      > > >
      > > > (F is non-virtual, DoF is protected virtual and probably abstract)
      > > >
      > > > int base::F(int i)
      > > > {
      > > > int ret;
      > > > if (IsParamInRange (i))
      > > > ret = DoF(i);
      > > > if (IsRetInRange(r et))
      > > > return ret;
      > > > else
      > > > return someError;
      > > > }
      > > >
      > > > The idea is to force everyone to use a common "entry point"
      > > > to some functionality with derived classes implementing specific
      > > > tasks.
      > > >
      > > > Andrew
      > > >
      > > > "Adrian Herscu" <bmf1972@hotmai l.com> wrote in message
      > > > news:%23yqf0Qug DHA.2352@TK2MSF TNGP09.phx.gbl. ..
      > > > > Hi all,
      > > > >
      > > > > In which circumstances it is appropriate to declare methods as
      > > > non-virtual?
      > > > >
      > > > > Thanx,
      > > > > Adrian.
      > > > >
      > > > >
      > > >
      > > >[/color]
      > >
      > >[/color]
      >
      >[/color]


      Comment

      • Jon Skeet

        #18
        Re: Non-virtual methods - why?

        Adrian Herscu <bmf1972@hotmai l.com> wrote:[color=blue][color=green][color=darkred]
        > > > 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]
        >
        > No - the principal feature of being non-virtual, is that non-virtual methods
        > are resolved at compile-time (a.k.a. static or early binding), so a call
        > *always* executes the same implementation.[/color]

        And that's exactly what a method not being overridable gives you.
        [color=blue][color=green][color=darkred]
        > > > In Java, methods can be hidden only by static methods - so, Java has no
        > > > concept of non-virtual methods.[/color]
        > >
        > > No, it has no concept of instance methods hiding other instance
        > > methods, which I view as being separate from having no concept of non-
        > > virtual methods.[/color]
        >
        > Think again. *Only* non-virtual methods can be "hidden".[/color]

        Not sure where you get that from:

        using System;

        class Base
        {
        public virtual void Foo()
        {
        Console.WriteLi ne ("Base.Foo") ;
        }
        }

        class Derived : Base
        {
        public new void Foo()
        {
        Console.WriteLi ne ("Derived.Foo") ;
        }
        }

        public class Test
        {
        static void Main()
        {
        Base b = new Derived();
        Derived d = new Derived();

        b.Foo();
        d.Foo();
        }
        }

        Base.Foo is clearly a virtual method, but as far as I can see
        Derived.Foo hides it in exactly the same way as if it were non-virtual.
        Take away the keyword "new" and you get a warning:

        <quote>
        Test.cs(13,17): warning CS0114: 'Derived.Foo()' hides inherited member
        'Base.Foo()'. To make the current member override that implementation,
        add the override keyword. Otherwise add the new keyword.
        </quote>
        [color=blue][color=green]
        > > In my view, they can be sealed to prevent them being virtual any
        > > further.[/color]
        >
        > "...virtual any further" = "...overrid en any further"[/color]

        Yes.
        [color=blue][color=green]
        > > My way of looking at things is that something is virtual if it can be
        > > overridden, and is non-virtual if it can't.
        > >
        > > 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]
        >
        > OK - but you can still hide it.[/color]

        Yes, and what's your point? You can hide a non-virtual method in C#.
        You can't in Java. That doesn't stop it from being non-virtual.
        [color=blue][color=green]
        > > 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]
        >
        > A final method in Java absolutely does *not* satisfy the descriptions of
        > non-virtual methods above - simply because you cannot hide it as you can in
        > C#.[/color]

        Where in that quote does it say that you have to be able to hide a
        method in order for it not to be virtual?
        [color=blue]
        > Moreover, even a C# "sealed" method which is the most close to a Java
        > "final" method, can be hidden by further subclasses[/color]

        Yes, but as I've said, I see hiding as separate notions. You seem to as
        well below:
        [color=blue]
        > There are two separate notions:
        > 1) Overriding - by overriding, a subclass replaces method pointers in
        > object's v-table and since all method invokations are made through that
        > v-table, you will always get the overriding implementation no matter from
        > which site you call it (either from superclass' site or from subclass'
        > site) - hence, dynamic binding. Also, that's the reason for naming those
        > methods "virtual" - because their implementation is not known until
        > run-time.[/color]
        [color=blue]
        > 2) Hidding - this is a totally different mechanism: method invokations are
        > resolved during compile-time (static binding); so, there is no v-table to go
        > through - the call is direct.[/color]

        Well, unless the new method is also virtual, of course, in which case
        you still need a v-table. (If you add an extra class D to your example
        which extends D and overrides M2, then do

        C x = new D();
        C.M2();

        then D.M2 will get executed.
        [color=blue]
        > In summary: when you call a non-virtual method, you will _always_ get the
        > same implementation executed; when you call a virtual method, you will *not*
        > always get the same implementation executed - it depends on the overriding
        > subclasses.[/color]

        And what part of that summary (which doesn't mention hiding, note)
        doesn't apply to final methods in Java?
        [color=blue]
        > //++ run this test ++++++[/color]

        Why? What do you think it shows? I know what is called... I don't see
        why you think that the test shows that Java doesn't have non-virtual
        methods.

        --
        Jon Skeet - <skeet@pobox.co m>
        Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

        If replying to the group, please do not mail me too

        Comment

        • Jon Skeet

          #19
          Re: Non-virtual methods - why?

          100 <100@100.com> wrote:[color=blue][color=green]
          > > And that, as far as I'm concerned, is the principal feature of being
          > > non-virtual.[/color][/color]
          [color=blue]
          > 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.[/color]

          No it's not.

          <snip>
          [color=blue]
          > A a = new C()
          > a.f() calls C.f()
          > Isn't it virtual?[/color]

          A.f is virtual,but C.f isn't, because you can't override it in a class
          that derives from C.
          [color=blue]
          > If it wasn't it would call A.f()[/color]

          Nope. From the C# specification again:

          <quote>
          The implementation of a virtual member can be changed by an overriding
          member in a derived class.
          </quote>

          Now, can you override f() in a class derived directly from C? No? Then
          it's not virtual.
          [color=blue]
          > *sealed* modifier force you to stop using overriden until you don't use
          > *virtual* again and then you can continue override the method.[/color]

          You can never override the actual sealed method. You can hide it with
          another virtual method and then override *that*, but that's not
          actually overriding the sealed (non-virtual) method.
          [color=blue]
          > BTW the
          > compiler generates *callvirt* instruction as a evidence of that the method
          > is indeed *virtual*[/color]

          That's evidence of A.f() being virtual, not evidence of C.f() being
          virtual.
          [color=blue][color=green]
          > > 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.[/color]

          No you can't.
          [color=blue]
          > what
          > you have to is to declared it as virtual again(to start new virtual
          > implemetation).[/color]

          You also have to declare it as "new" and *hide* the previous method.
          That's *not* overriding it.
          [color=blue]
          > 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.[/color]

          The CLR doesn't take that into account; the compiler does.
          [color=blue]
          > To be more strict
          > callvirt is provided with the name of the class from where to start looking
          > for the most-derived implementation.[/color]

          Yes, but it will stop when it gets to a sealed method. In other words,
          there's no way that you can write a class MyDerivedClass such that

          C c = new MyDerivedClass( );
          c.f();

          will call anything other than c.f();

          (assuming you don't change C itself).

          If you think you can, please demonstrate it.
          [color=blue][color=green]
          > > 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).[/color]

          Indeed, but that's irrelevant.
          [color=blue]
          > The modifier *override* already means that the method is virtual.[/color]

          No, it means the method in the class it's deriving from is virtual.

          <snip>
          [color=blue]
          > 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]

          That doesn't change the implementation though - it just provides a new
          method. It doesn't change the implementation in the same way that
          overriding does.
          [color=blue][color=green]
          > > 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.[/color]

          It's different from C# due to the fact that you can't hide it, but that
          doesn't mean it's non-virtual. You can't hide it just because you can't
          hide methods at all in Java. If we were to apply your logic above, we'd
          also come to the conclusion that there aren't any virtual methods in
          Java either, as they can't be hidden. Do you really believe that every
          method in Java is neither virtual nor non-virtual?
          [color=blue]
          > Non-virtual methods cannot be overriden - OK. One can hide then, though.[/color]

          You don't *have* to be able to hide them in order for them to be non-
          virtual though! Hiding's just a different concept in the same area.
          [color=blue]
          > So my question is: Why C# allows virtual methods to be hidden. Isn't it
          > error prone.[/color]

          Not really, because there's a warning message if you try to do it.
          [color=blue]
          > I believe that the best is:
          > 1. To have virtual and non-virtual methods.[/color]

          Which both C# and Java have.
          [color=blue]
          > 2. Sealing virtual methods has to prevent further overriding and hiding the
          > methods.[/color]

          I disagree with this - a warning is all that's required to avoid
          hiding. Sealing an otherwise virtual method makes it non-virtual, and
          that's all that's required.
          [color=blue]
          > 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.[/color]

          I don't think that was the reason at all. I think it was to prevent
          classes from breaking when they're recompiled against newer versions of
          libraries they may use. You get a warning if you try to hide a member
          (because the member may not have existed before), but you get the same
          behaviour, and can remove the warning by explicitly saying that that's
          what you wanted to do. Don't forget that this method may itself be part
          of a public API which can't easily be changed.

          --
          Jon Skeet - <skeet@pobox.co m>
          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

          If replying to the group, please do not mail me too

          Comment

          • Eric Gunnerson [MS]

            #20
            Re: Non-virtual methods - why?

            Anders answers this here:



            --
            Eric Gunnerson

            Visit the C# product team at http://www.csharp.net
            Eric's blog is at http://blogs.gotdotnet.com/ericgu/

            This posting is provided "AS IS" with no warranties, and confers no rights.
            "Adrian Herscu" <bmf1972@hotmai l.com> wrote in message
            news:%23yqf0Qug DHA.2352@TK2MSF TNGP09.phx.gbl. ..[color=blue]
            > Hi all,
            >
            > In which circumstances it is appropriate to declare methods as[/color]
            non-virtual?[color=blue]
            >
            > Thanx,
            > Adrian.
            >
            >[/color]


            Comment

            • Mike Schilling

              #21
              Re: Non-virtual methods - why?


              "Jon Skeet" <skeet@pobox.co m> wrote in message
              news:MPG.19dd8f d454ce10a798976 d@msnews.micros oft.com...[color=blue]
              > Adrian Herscu <bmf1972@hotmai l.com> wrote:[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]

              In fact, in C# a non-virtual method which implements an interface method is
              actually compiled into a "virtual sealed" method. The only way to tell this
              is with ILDASM, since it acts exactly like a non-virtual method.


              Comment

              • Jon Skeet

                #22
                Re: Non-virtual methods - why?

                Eric Gunnerson [MS] <ericgu@online. microsoft.com> wrote:[color=blue]
                > Anders answers this here:
                >
                > http://www.artima.com/intv/nonvirtualP.html[/color]

                Shame Anders has a pretty dodgy section in that article:

                <quote>
                Anders Hejlsberg: There are several reasons. One is performance. We can
                observe that as people write code in Java, they forget to mark their
                methods final. Therefore, those methods are virtual. Because they're
                virtual, they don't perform as well. There's just performance overhead
                associated with being a virtual method. That's one issue.
                </quote>

                In modern Java VMs (or at least HotSpot), methods are actually treated
                as non-virtual until they are overridden, whereupon code which calls
                the overridden method is rejitted to make a virtual call. Of course,
                this trickery may well have been included only because so many methods
                in Java *are* virtual, but I still think it's important to note.

                (I agree with the rest of the article though :)

                --
                Jon Skeet - <skeet@pobox.co m>
                Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                If replying to the group, please do not mail me too

                Comment

                • Adrian Herscu

                  #23
                  Re: Non-virtual methods - why?

                  > > Think again. *Only* non-virtual methods can be "hidden".[color=blue]
                  >
                  > Not sure where you get that from:
                  >
                  > using System;
                  >
                  > class Base
                  > {
                  > public virtual void Foo()
                  > {
                  > Console.WriteLi ne ("Base.Foo") ;
                  > }
                  > }
                  >
                  > class Derived : Base
                  > {
                  > public new void Foo()
                  > {
                  > Console.WriteLi ne ("Derived.Foo") ;
                  > }
                  > }
                  >
                  > public class Test
                  > {
                  > static void Main()
                  > {
                  > Base b = new Derived();
                  > Derived d = new Derived();
                  >
                  > b.Foo();
                  > d.Foo();
                  > }
                  > }
                  >
                  > Base.Foo is clearly a virtual method, but as far as I can see
                  > Derived.Foo hides it in exactly the same way as if it were non-virtual.
                  > Take away the keyword "new" and you get a warning:
                  >[/color]

                  Base::Foo is clearly declared virtual, but it is not really virtual !
                  If it were virtual then:

                  Base b = new Derived();
                  b.Foo();

                  would output:

                  Derived.Foo

                  That's exactly the semantics of being non-virtual.

                  And again, "final" in Java is very different from non-virtual - a
                  non-virtual method can be hidden, but a "final" method cannot be hidden.


                  Comment

                  • Jon Skeet

                    #24
                    Re: Non-virtual methods - why?

                    Adrian Herscu <bmf1972@hotmai l.com> wrote:[color=blue][color=green]
                    > > Base.Foo is clearly a virtual method, but as far as I can see
                    > > Derived.Foo hides it in exactly the same way as if it were non-virtual.
                    > > Take away the keyword "new" and you get a warning:[/color]
                    >
                    > Base::Foo is clearly declared virtual, but it is not really virtual ![/color]

                    Yes it is. You could create another class which overrides it, and that
                    would be called if you had:

                    Base b = new OtherDerived();
                    b.Foo();

                    A virtual method doesn't have to actually have *been* overridden to be
                    virtual.
                    [color=blue]
                    > If it were virtual then:
                    >
                    > Base b = new Derived();
                    > b.Foo();
                    >
                    > would output:
                    >
                    > Derived.Foo[/color]

                    No, that's what would happen if Derived.Foo overrode Base.Foo. It
                    doesn't, but that's because of Derived.Foo hiding Base.Foo, not because
                    Base.Foo isn't virtual in the first place. How can the presence or
                    absence of another method change whether or not a method is virtual?
                    [color=blue]
                    > That's exactly the semantics of being non-virtual.[/color]

                    Nope. The semantics of being non-virtual is that the method can't be
                    overridden.
                    [color=blue]
                    > And again, "final" in Java is very different from non-virtual - a
                    > non-virtual method can be hidden, but a "final" method cannot be hidden.[/color]

                    But a virtual method can't be hidden either in Java! Whether or not a
                    method is virtual or not has *nothing* to do with whether or not the
                    language supports hiding.

                    --
                    Jon Skeet - <skeet@pobox.co m>
                    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                    If replying to the group, please do not mail me too

                    Comment

                    • Pete

                      #25
                      Re: Non-virtual methods - why?

                      Hi,

                      Jon Skeet wrote:[color=blue]
                      > In modern Java VMs (or at least HotSpot), methods are actually treated
                      > as non-virtual until they are overridden, whereupon code which calls
                      > the overridden method is rejitted to make a virtual call. Of course,
                      > this trickery may well have been included only because so many methods
                      > in Java *are* virtual, but I still think it's important to note.[/color]

                      So if you need that extra performance (but I can't think of a good reason
                      why you would), you have to try and guess what the Java jitter is going to
                      do?

                      Interesting that he says virtual and override say different things.. I
                      hadn't thought of it that way before.

                      -- Pete


                      Comment

                      • Jon Skeet

                        #26
                        Re: Non-virtual methods - why?

                        Pete <pvidler@gawab. com> wrote:[color=blue]
                        > Jon Skeet wrote:[color=green]
                        > > In modern Java VMs (or at least HotSpot), methods are actually treated
                        > > as non-virtual until they are overridden, whereupon code which calls
                        > > the overridden method is rejitted to make a virtual call. Of course,
                        > > this trickery may well have been included only because so many methods
                        > > in Java *are* virtual, but I still think it's important to note.[/color]
                        >
                        > So if you need that extra performance (but I can't think of a good reason
                        > why you would), you have to try and guess what the Java jitter is going to
                        > do?[/color]

                        Not really - it's not like you have to change your code to take
                        advantage of it. Knowing what the JIT is capable of (and its
                        limitations) is likely to help though - and that's not unique to Java
                        by any means. It's a bit of a chicken-and-egg situation. The more you
                        know about how any one implementation of the CLR or Java VM works, the
                        better you're likely to be able to write code for that particular
                        archiecture - but what's good for one might be awful for another. For
                        instance, with one garbage collector and heap allocator, object pooling
                        could be a really good idea; with another, it might be something to
                        avoid.
                        [color=blue]
                        > Interesting that he says virtual and override say different things.. I
                        > hadn't thought of it that way before.[/color]

                        I'm not exactly sure about which bit you mean, but yes - it's generally
                        good stuff.

                        --
                        Jon Skeet - <skeet@pobox.co m>
                        Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                        If replying to the group, please do not mail me too

                        Comment

                        • Adrian Herscu

                          #27
                          Re: Non-virtual methods - why?

                          1.
                          A virtual method has to execute the same implementation, no matter through
                          which interface it was invoked.
                          And in your example, it does matter.

                          IMHO, the "virtual" term is not about declarations, it's about behavior. So,
                          if a method doesn't behave as "virtual", then it is not virtual.

                          At the end, (in C#) it depends on the direct subclass if a declared virtual
                          method is actually virtual.
                          And this is a fundamental difference between C# and the others (C++ and
                          Java):
                          In C++, a declared virtual method will always be overridden by a subclass
                          owning a method with the same signature.
                          In Java all non-finalized instance methods are virtual.

                          2.
                          Consider this:

                          using System;

                          class Base {
                          static private void DoBaseFoo() { Console.WriteLi ne("Did Base Foo"); }
                          public void Foo() { DoBaseFoo(); }
                          }

                          class Derived : Base {
                          static private void DoDerivedFoo() { Console.WriteLi ne("Did Derived
                          Foo"); }
                          new public void Foo() { DoDerivedFoo(); }
                          }

                          class TestNonVirtual {
                          static public void Main() {
                          Object d = new Derived();

                          ((Base)d).Foo() ; // This will execute DoBaseFoo()
                          ((Derived)d).Fo o(); // and this will execute DoDerivedFoo().

                          /*
                          That is because Base::Foo is non-virtual not only by
                          declaration,
                          but also by behavior.
                          */
                          }
                          }

                          Can you build such a thing in Java? If you can, then Java supports
                          non-virtual methods.

                          "Jon Skeet" <skeet@pobox.co m> wrote in message
                          news:MPG.19dff8 b21f8e6dad98978 0@msnews.micros oft.com...[color=blue]
                          > Adrian Herscu <bmf1972@hotmai l.com> wrote:[color=green][color=darkred]
                          > > > Base.Foo is clearly a virtual method, but as far as I can see
                          > > > Derived.Foo hides it in exactly the same way as if it were[/color][/color][/color]
                          non-virtual.[color=blue][color=green][color=darkred]
                          > > > Take away the keyword "new" and you get a warning:[/color]
                          > >
                          > > Base::Foo is clearly declared virtual, but it is not really virtual ![/color]
                          >
                          > Yes it is. You could create another class which overrides it, and that
                          > would be called if you had:
                          >
                          > Base b = new OtherDerived();
                          > b.Foo();
                          >
                          > A virtual method doesn't have to actually have *been* overridden to be
                          > virtual.
                          >[color=green]
                          > > If it were virtual then:
                          > >
                          > > Base b = new Derived();
                          > > b.Foo();
                          > >
                          > > would output:
                          > >
                          > > Derived.Foo[/color]
                          >
                          > No, that's what would happen if Derived.Foo overrode Base.Foo. It
                          > doesn't, but that's because of Derived.Foo hiding Base.Foo, not because
                          > Base.Foo isn't virtual in the first place. How can the presence or
                          > absence of another method change whether or not a method is virtual?
                          >[color=green]
                          > > That's exactly the semantics of being non-virtual.[/color]
                          >
                          > Nope. The semantics of being non-virtual is that the method can't be
                          > overridden.
                          >[color=green]
                          > > And again, "final" in Java is very different from non-virtual - a
                          > > non-virtual method can be hidden, but a "final" method cannot be hidden.[/color]
                          >
                          > But a virtual method can't be hidden either in Java! Whether or not a
                          > method is virtual or not has *nothing* to do with whether or not the
                          > language supports hiding.
                          >
                          > --
                          > Jon Skeet - <skeet@pobox.co m>
                          > http://www.pobox.com/~skeet
                          > If replying to the group, please do not mail me too[/color]


                          Comment

                          • Adrian Herscu

                            #28
                            Re: Non-virtual methods - why?

                            Sounds like programmers will develop dependence on some particular
                            implementation.
                            As a driver, I don't care if my car engine has a central-point injection or
                            multi-point injection system - I will use it the same way!

                            "Jon Skeet" <skeet@pobox.co m> wrote in message
                            news:MPG.19e0d7 b7cd11effb98978 9@msnews.micros oft.com...[color=blue]
                            > Pete <pvidler@gawab. com> wrote:[color=green]
                            > > Jon Skeet wrote:[color=darkred]
                            > > > In modern Java VMs (or at least HotSpot), methods are actually treated
                            > > > as non-virtual until they are overridden, whereupon code which calls
                            > > > the overridden method is rejitted to make a virtual call. Of course,
                            > > > this trickery may well have been included only because so many methods
                            > > > in Java *are* virtual, but I still think it's important to note.[/color]
                            > >
                            > > So if you need that extra performance (but I can't think of a good[/color][/color]
                            reason[color=blue][color=green]
                            > > why you would), you have to try and guess what the Java jitter is going[/color][/color]
                            to[color=blue][color=green]
                            > > do?[/color]
                            >
                            > Not really - it's not like you have to change your code to take
                            > advantage of it. Knowing what the JIT is capable of (and its
                            > limitations) is likely to help though - and that's not unique to Java
                            > by any means. It's a bit of a chicken-and-egg situation. The more you
                            > know about how any one implementation of the CLR or Java VM works, the
                            > better you're likely to be able to write code for that particular
                            > archiecture - but what's good for one might be awful for another. For
                            > instance, with one garbage collector and heap allocator, object pooling
                            > could be a really good idea; with another, it might be something to
                            > avoid.
                            >
                            > --
                            > Jon Skeet - <skeet@pobox.co m>
                            > http://www.pobox.com/~skeet
                            > If replying to the group, please do not mail me too[/color]


                            Comment

                            • Jon Skeet

                              #29
                              Re: Non-virtual methods - why?

                              Adrian Herscu <bmf1972@hotmai l.com> wrote:[color=blue]
                              > 1.
                              > A virtual method has to execute the same implementation, no matter through
                              > which interface it was invoked.
                              > And in your example, it does matter.[/color]

                              Only because the virtual method doesn't enter into it - the hiding
                              method means that it's called instead of a virtual call being made.
                              That has nothing to do with whether or not the base method is virtual.
                              [color=blue]
                              > IMHO, the "virtual" term is not about declarations, it's about behavior. So,
                              > if a method doesn't behave as "virtual", then it is not virtual.[/color]

                              I disagree entirely. A method doesn't just "become" virtual due to
                              having been overridden elsewhere. A method is virtual if it *can* be
                              overridden. That's all there is to it. Note that you're also
                              disagreeing with the C# language specification here, which says:

                              <quote>
                              When an instance method declaration includes a virtual modifier, that
                              method is said to be a virtual method.
                              </quote>

                              Do you at least agree, given that your above, that your idea of a
                              method being virtual is not the same as the C# language specification's
                              idea?
                              [color=blue]
                              > At the end, (in C#) it depends on the direct subclass if a declared virtual
                              > method is actually virtual.[/color]

                              No it doesn't - because otherwise you've got the situation where it's
                              half-virtual and half-not-virtual, if it's overridden in one class and
                              hidden in another.
                              [color=blue]
                              > And this is a fundamental difference between C# and the others (C++ and
                              > Java):
                              > In C++, a declared virtual method will always be overridden by a subclass
                              > owning a method with the same signature.
                              > In Java all non-finalized instance methods are virtual.[/color]

                              Which means that finalized instance methods are non-virtual, as I said
                              before and which you disagreed with.
                              [color=blue]
                              > 2.
                              > Consider this:
                              >
                              > using System;
                              >
                              > class Base {
                              > static private void DoBaseFoo() { Console.WriteLi ne("Did Base Foo"); }
                              > public void Foo() { DoBaseFoo(); }
                              > }
                              >
                              > class Derived : Base {
                              > static private void DoDerivedFoo() { Console.WriteLi ne("Did Derived
                              > Foo"); }
                              > new public void Foo() { DoDerivedFoo(); }
                              > }
                              >
                              > class TestNonVirtual {
                              > static public void Main() {
                              > Object d = new Derived();
                              >
                              > ((Base)d).Foo() ; // This will execute DoBaseFoo()
                              > ((Derived)d).Fo o(); // and this will execute DoDerivedFoo().
                              >
                              > /*
                              > That is because Base::Foo is non-virtual not only by
                              > declaration,
                              > but also by behavior.
                              > */
                              > }
                              > }
                              >
                              > Can you build such a thing in Java? If you can, then Java supports
                              > non-virtual methods.[/color]

                              No, but I don't *need* to for Java to support non-virtual methods. I
                              repeat, hiding is *not* a necessity for non-virtual methods to be
                              supported.

                              As you said before:
                              "In Java all non-finalized instance methods are virtual."

                              So what are finalized instance methods? Are they virtual or are they
                              not, according to your understanding?

                              --
                              Jon Skeet - <skeet@pobox.co m>
                              Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                              If replying to the group, please do not mail me too

                              Comment

                              • Adrian Herscu

                                #30
                                Re: Non-virtual methods - why?

                                I agree on that there are multiple perspectives.
                                About specs in general - they are not holly scripts (yet).

                                Anyway, the original question was: "In which circumstances it is appropriate
                                to declare methods as non-virtual?".

                                I read Anders' interview, and the answer to the above question is burried
                                somewere in.

                                Thank you all,
                                Adrian.


                                Comment

                                Working...