virtual properties?

M

^MisterJingo^

Is it good pratice to make base class properties virtual? For example:

public abstract class Person
{
protected string name;
public virtual string Name
{
//get, set stuff here
}
}

public class Student : Person
{

}

In the above example the property just sets and gets the 'name' member.
I can't see any need for student to override it, but in the future that
might not be the case.
Should we attempt to 'future proof' the code where possible?

Chris
 
N

Nicholas Paldino [.NET/C# MVP]

MisterJingo,

Without knowing what the code will be used for, as well as what you are
modelling with it, it's impossible to really say whether or not it should be
"future-proofed" as you say.

Sure, you could mark every method as virtual, but that's not going to do
you much good.

If you can't see the meaning Name property being changed, or the need
for customization, then I would not bother making it virtual.

Hope this helps.
 
J

Jon Skeet [C# MVP]

^MisterJingo^ said:
Is it good pratice to make base class properties virtual? For example:

public abstract class Person
{
protected string name;
public virtual string Name
{
//get, set stuff here
}
}

public class Student : Person
{

}

In the above example the property just sets and gets the 'name' member.
I can't see any need for student to override it, but in the future that
might not be the case.
Should we attempt to 'future proof' the code where possible?

Personally, I'd advise against it. Overriding should never be done on a
casual basis - a class really needs to be designed for derivation.
Otherwise, you could have two methods where the base implementation of
the first calls the second - you could easily override the second
method and (unaware of the implementation of the first) call the first.
That's just one example - there are plenty of others. Basically, you
need to document far more about a class if you're designing it for
derivation, and its implementation can't change nearly as easily, as
the calls to virtual methods effectively need to be documented as part
of the contract.
 
M

Michael S

^MisterJingo^ said:
Is it good pratice to make base class properties virtual? For example:

public abstract class Person
{
protected string name;
public virtual string Name
{
//get, set stuff here
}
}

public class Student : Person
{

}

In the above example the property just sets and gets the 'name' member.
I can't see any need for student to override it, but in the future that
might not be the case.
Should we attempt to 'future proof' the code where possible?

Chris

I seldom try to create a huge framework of classes until I know I'll need
it.

Time is Money and very often I see so called architects creating this huge
stack of classes that are hardly, if all, used - only adding complexity to
the system.

Hence, I would just implement Student derived from Object. If I later need a
Teacher and KNOW I'll treat them polymorphically (perhaps having a list of
Students and Teachers while the list only call overriden methods on Persons)
I would add the class. I would never introduce Person until I know I'd use
it.

But then again, this is true for applications in your control. If you are
creating some components that other people/companies will use, it is better
to spend some time on the framework and try to guess how the components may
change and expand in the future.

Also, not much in the world is polymorphic. It is great for GUI-frameworks
and Streams and such, but for most things interfaces is more flexible.

Let's say you want to .Kill() Students and Teachers. While they are both
Persons and therefor could be a abstract method of this class, I would
rather define a IKillable interface and implement them where I saw fit. My
Assassin-class could then learn to .Kill() most Animals (but not Cats) and
most Computers (except for Crays), and not only (and every) Person.

Hope this helped
- Michael S
 
L

Leon Lambert

Jon said:
Personally, I'd advise against it. Overriding should never be done on a
casual basis - a class really needs to be designed for derivation.
Otherwise, you could have two methods where the base implementation of
the first calls the second - you could easily override the second
method and (unaware of the implementation of the first) call the first.
That's just one example - there are plenty of others. Basically, you
need to document far more about a class if you're designing it for
derivation, and its implementation can't change nearly as easily, as
the calls to virtual methods effectively need to be documented as part
of the contract.
I don't nessesarily disagree, but it sure can get frustrating when you
need to add a tiny bit of behavior to a standard class and can't
override the method you need. This forces you to use encapsulation to
accomplish it or create a subclass with a new method. Now none of the
methods that accepted the old class will take the new forcing you into a
lot more work. I agree this doesn't happen often but when it does it is
extremely frustrating. Java's methods are virtual by default and seem to
cause a little less stress in this area. I think .Net took the other
route so the Jitter can be simplier and not have to analyze if a method
was over-ridden and make direct method calls instead of calling indirect
through a VTable.

Leon Lambert
 
M

Michael S

I don't nessesarily disagree, but it sure can get frustrating when you
need to add a tiny bit of behavior to a standard class and can't override
the method you need. This forces you to use encapsulation to accomplish it
or create a subclass with a new method. Now none of the methods that
accepted the old class will take the new forcing you into a lot more work.
I agree this doesn't happen often but when it does it is extremely
frustrating. Java's methods are virtual by default and seem to cause a
little less stress in this area. I think .Net took the other route so the
Jitter can be simplier and not have to analyze if a method was over-ridden
and make direct method calls instead of calling indirect through a VTable.

Leon Lambert

That's not really the true story. Actually a JavaJitter will optimize
leaf-classes and treat them as non-virtual for perfomance.

The real deal here is that Anders Hejlsberg borrowed this approach from his
Delphi. It also have default non-virtual methods. It tries to save us from
unwanted polymorphism.

I gave this example a few days before, but here we go again..

I write the class Thingy and a set of cool classes that operates on
Thingys.You like my class but you want to add stuff to it; so you subclass
it into MyThingy. One method you add is .DoStuff(). Now a ship a 1.1 version
of my Thingy library and you add that to the project. But what you didn't
look for was that I added the method .DoStuff().

In Java the problem is two-folded. As methods are virtual and there is no
keyword for overriding methods, you just overridden my method. That means
that whenever my cool classes tries to calls DoStuff() your code will be
executed. That gives for some weird bugs. And when you wrote your method you
had no Super() to call on, so my code doesn't get executed at all. The
thingy will probably be in a corrupt state. And all this just happened
without you even knowing. The compiler compiles away happily.

In C# (and Delphi) methods are not virtual by default. When a collission in
names occur you get a compile-time error telling you to either reintroduce
the method or rename it. If it is virtual you can override it.

In this example the good thing for you would be to rename your method as
ours have nothing to do with eachother.

But you could reintroduce it and everything works just fine. The Thingy
classes only have references to Thingy and so my classes would call my
methods. You only have references to MyThingy and so your methods will be
called from your code.

But then again, the best would be to rename your method.

When a class-developer plans his methods he make these statements:

virtual - This method should be used in a polymoprhic behavour and my code
is so general that it will work for all possible subclasses you can think
of.

non-virtual - This method does stuff. If you don't like stuff you can always
reintroduce and replace whatever code you want. I don't care. You're on your
own.

And as you see, you don't need to create a wrapper. You can often
reintroduce.

Happy Coding
- Michael S
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top