Click to See Complete Forum and Search --> : [RESOLVED] Inheritance and Polymorphism
Brent Burgess
Sep 30th, 2009, 09:19 PM
Hi all,
As part of my VB.NET Course, I am required to talk to:
"Discuss inheritance and polymorphism with computer experts to find answers to the following questions. If you can locate a user of VB.NET, ask about their experiences."
Inheritance
Is inheritance generally understood by programmers?
Is it widely used?
When might it be used?
What limitations, if any, restrict its use?
Polymorphism
Is Polymorphism generally understood by programmers?
Is it widely used?
Does VB.NET assist with the use of Polymorphism, and how?
When might Polymorphism be used? Give specific examples.
What limitations, if any, restrict its use?
Is anybody able to offer some insight into this? To me, the questions leave a lot to opinnions, rather than fact, but would love to hear other peoples thoughts.
Thanks in advance.
Brent
FunkyDexter
Oct 1st, 2009, 05:02 AM
Just my opinions really but:-
Is inheritance generally understood by programmers?
I think it varies but increasingly Yes. Basically any programmers whose learned their craft since OO came about probably at least understands the concepts.
Is it widely used?
It's not used anywhere near as widely as it's understood. While most OO programmers get the idea, alot are put off by horror stories of over-burdened inheritance trees which can be a real killer for a project. Also, I think alot are just afraid to try it out because you never actually need it and they find it easier to stick with what they know. Whether or not it's widely used depends on how you define 'widely' but it's certainly not uncommon.
When might it be used?Peronally I've found it most useful in UI code. We implement our own controls and those, of course, inherit from the base controls. And we also implement some basic form types (an edit form, a print form, a display form etc) and then inherit from them when we want a specific implementation. Finally we also make heavy use of a basic user control that we then inherit from. Basically, we've built a model where our forms and user controls all know how to populate and save themselves. The basic code to do the populating, clearing, saving, switching between new and edit mode, displaying errors etc is all in the base edit form and user control so we only have to write that stuff once. We then inherit the specific implementations from those. Everything's overridable so if, for example, the base implementation of save isn't suitable for a specific form we can replace or extend it without any real difficulty. I hope that gives you a good example without boring you to death with our own aproach.
What limitations, if any, restrict its use?Basically, don't use it unless it's giving you a benefit. That rule's the same for all these kind of concepts. As mentioned previously, using it for the hell of it detracts from the maintainability of your code which is exactly the opposite of the desired effect.
I need to get back to work now so I'll skip polymorphism and maybe post back at lunch time :)
Jenner
Oct 1st, 2009, 07:50 AM
FunkyDexter provided a stellar response to Inheritance, with which I agree 110%.
Is Polymorphism generally understood by programmers?
Yes, although VB.NET programmers know it more commonly as "Overloading". Typically though, it's fairly well understood by programmers.
Is it widely used?
I'd like to say it's used perhaps more so than inheritance. You see examples of it every day via the Intellisense of the IDE and once programmers realize they can overload different sets of arguments onto a single function name, they tend to adopt it pretty quickly. After all, there are many cases where you may have all the data you need for a function, just not exactly in the data types you need.
Does VB.NET assist with the use of Polymorphism, and how?
VB.NET has two forms of polymorphism, Overloading which is fairly transparent, and the Optional statement. Overloading means the function is listed in multiple function blocks with the same name, but just different sets of arguments and possibly different return types.
The Optional statement means that you can, within a single function block, have an argument marked as optional and have an assigned, discreet default value.
Yes, you can use both together as well. the Optional statement is much more limited in scope and Overloading can do everything the Optional statement can do. Use of the Optional statement is more typically reserved for if you have a single set of arguments to a function; thus don't need to really overload it, but want to make one of those arguments optional with a default value and don't want to make a second function block. It makes the code look tidier as well.
When might Polymorphism be used? Give specific examples.
Whenever you want to call a single function; but have different ways to express your arguments; or have optional arguments. A simple example would be a Convert.ToInt32() type function. They all produce the same return type: Int32 obviously, but the argument can be various datatypes:
Convert.ToInt32(arg As Decimal) As Int32
Convert.ToInt32(arg As Double) As Int32
Convert.ToInt32(arg As Single) As Int32
Convert.ToInt32(arg As String) As Int32
Convert.ToInt32(arg As Boolean) As Int32
Another example would be to have an optional argument. Suppose you got a function to draw a rectangle on the screen. You could optionally have an argument for it's color:
DrawRect(x1 As Int32, y1 As Int32, x2 As Int32, y2 As Int32)
DrawRect(x1 As Int32, y1 As Int32, x2 As Int32, y2 As Int32, color As Color)
And when used both together, maybe that DrawRect function can also take Drawing.Rectangle objects instead of just points:
DrawRect(x1 As Int32, y1 As Int32, x2 As Int32, y2 As Int32)
DrawRect(x1 As Int32, y1 As Int32, x2 As Int32, y2 As Int32, color As Color)
DrawRect(rect As Drawing.Rectangle)
DrawRect(rect As Drawing.Rectangle, color As Color)
What limitations, if any, restrict its use?
None really that I'm aware of. Unlike Inheritance, use of functional polymorphism doesn't cause nearly as much confusion since all the code is still together and not split across multiple files as it typically is with Inheritance. Granted, extreme examples would be a programmer who had one function called "A()" that took 60 different types of input and produced 20 different types of output, so as FunkyDexter said, use it in moderation like anything else.
Brent Burgess
Oct 1st, 2009, 08:02 AM
Thats excellent - I was guessing that is the type of responses I would get, opinions. But it gives me something to start with in writing my responses.
Shaggy Hiker
Oct 1st, 2009, 10:02 AM
Interesting, I have a totally different understanding of the definition of Polymorphism from what Jenner stated. Therefore, I would suggest that there is at least some disagreement about that subject.
In my view, polymorphism means runtime polymorphism, not overloading. Runtime polymorphism is where you have a variety of child classes that all inherit from a common base:
Public Class MyBase
Public Sub MySub
Messagebox.Show("My base version")
End Sub
End Class
Public Class ChildA
Public Sub MySub
Messagebox.Show("A version")
End Sub
End Class
Public Class ChildB
Public Sub MySub
Messagebox.Show("B version")
End Sub
End Class
Since all instances of a derived class can be cast to an instance of their base, you can do something like this:
Dim mList as List (of MyBase)
mList.Add(New MyBase)
mList.Add(New ChildA)
mList.Add(New ChildB)
For x As Integer = 0 to mList.Count -1
mList(x).MySub
Next
It's a trivial example, but the List holds a bunch of MyBase, yet when you call MySub on each one, it calls the correct version based on the true type of the class. Therefore, the output would be:
"My base Version"
"A Version"
"B Version"
I'd say that this type of runtime polymorphism, which is key to OO design, is not very widely used, especially in .NET. I, personally, find it most applicable to modeling systems where all the elements in a system have the same set of responses, though each perform them differently.
Jenner
Oct 1st, 2009, 11:03 AM
"Polymorphic" by definition pretty much means: "One object, many names" so really, in OO design, there's lots of different examples of "Polymorphism", some of which are wildly different. I've always used it in reference to polymorphism on a functional level.
Yes, I can see Shaggy's example referring to "Polymorphism" as well, though he's referring to the more specific example of "Do programmers set it up and use it within their own, custom programmed classes?". In which I agree, it's probably not used much at all. I think I've only used it less than a handful of times since I usually know precisely what classes I'm dealing with, and don't have to drop backwards to functionality from some parent class.
The .NET framework on the other hand is built on it. Every time you call the .Text property from a Textbox, you're using it, since the Text property is actually handled within TextBoxBase object. Even the .ToString() method is an example of this type of Polymorphism. Everything in the framework is inherited from the Object class and .ToString() is a part of that. In that regard, programmers use it every day.
Shaggy Hiker
Oct 1st, 2009, 11:17 AM
Very good point. ToString is indeed polymorphic.
One thing about .NET is that it has Run Time Type Inference (RTTI) buit in, because you can always use GetType to determine what actual object you are working with, even if all you have is a variable of a base type. RTTI was fairly controversial when the C++ ANSI standard was being hashed out. Many people felt that it was never necessary because of polymorphism. .NET has it both ways, which just means that there are even more ways to skin the same cat. I don't see that as a particularly bad thing (though I could be convinced with some legacy error handling GOTOs).
penagate
Oct 1st, 2009, 08:56 PM
I think Shaggy's definition of polymorphism is the correct one, although I disagree that it is not widely used. Polymorphism is (in vague terms) the treatment of data variables with more regard to their function or behaviour than to their precise type. For example, by casting an object to a particular interface, one can be certain the object can perform the tasks specified in the interface (or at least that we can instruct it to) and its actual type is irrelevant. This often occurs in the data layer of an application: One might define an interface for data methods (such as saving and loading state), which can be implemented in different ways to suit particular data stores (such as different database systems). These methods can be called against an object of any type which conforms to the interface, thus achieving a level of abstraction: Outside the data layer, the programmer doesn't need to care how things are persisted behind the scenes.
Overloading is not an example of polymorphism because it only provides for the same behaviour to be implemented in the same class multiple times to suit different types of parameters. This is a more specific problem than implementing a set of behaviours across many classes. (The same problem could be solved in a polymorphic fashion by creating only one method which accepts any object of a particular interface... although this is often impractical.)
I have a more cynical view than the people above: I believe, in general, that most programming concepts are more widely used than they are understood, and — particularly in the case of object-orientation — where they are used, they are used in order to achieve a specific result, rather than because they are the most appropriate solution. Object-oriented programming itself is far more widely used than it is appropriate.
jmcilhinney
Oct 2nd, 2009, 12:42 AM
In VB.NET programming the "official" meaning of polymorphism is as Shaggy explained.
http://msdn.microsoft.com/en-us/library/z165t2xk.aspx
I have a more cynical view than the people above: I believe, in general, that most programming concepts are more widely used than they are understoodI have to agree with that. VB.NET programmers are using both inheritance and polymorphism all the time without even realising it. For instance, every time we use data-binding we are using polymorphism because, in WinForms, we can bind any object that implements the IList or IListSource interface. How many people bind data to a DataGridView in their first few weeks of VB programming without ever having heard of polymorphism or interfaces? Also, every single type we define inherits the Object class at least, so even the greenest newbie uses inheritance.
I think that both are pretty much unavoidable in VB.NET, especially inheritance. I think that they are alsoboth not necessarily well understood except by those with considerable experience, especially polymorphism. Even those with intermediate experience levels often don't have a full understanding of the implications of polymorphism, even if they can put it to use. That's one of the great things about .NET programming: complex principles are so ingrained that they can be utilised without having to think to hard.
FunkyDexter
Oct 2nd, 2009, 04:37 AM
The way I was taught polymorphism in my degree was as Jenner described. That was in a java context though. In industry I've come across it more often as Shaggy described and that's usually been in a VB.Net or C++ context. That makes me think that the term isn't really properly defined and tends to get used slightly differently by different groups of programmers. That's just my impression though and one or the other might be 'official'. Oddly enough, it was that confusion that stopped me posting back about polymorphism - every time I tried I found I couldn't really articulate exactly what it was properly, let alone answer the questions Brent asked. Mind you, I guess that confusion goes some way to answering whether it's widely understood.
jmcilhinney
Oct 2nd, 2009, 05:28 AM
I've never actually heard the term "polymorphism" used in programming the way Jenner described it, or not that I can remember anyway, but when I read that I searched a bit and found both definitions used in various reputable places. Regardless, I think the answer to the question of understanding for either definition of polymorphism and inheritance comes down to experience. There are four of us in my office, one whom has been working with OOP for a couple of years and the rest for much longer. The three of us all have a pretty much full understanding of both inheritance and polymorphism of both types, even if we don't necessarily use that term, but the fourth wouldn't have a full understanding of either, especially polymorphism.
Jenner
Oct 2nd, 2009, 07:50 AM
Yea, I hunted around the web and found definitions for both as well, though I think I found my original definition and understanding from a book about VB.NET.
I think the terminologies for each are probably more at home in C++ where everything is built from the ground up, rather than on top of a platform like .NET or even Java. The platform of course is written using and supporting the OO principles of polymorphism and inheritance, but when you get to the part where the platform ends and the application begins, it's not so important.
Metaphor time :D :
Programming for a platform is like building an intricate pattern of lily pads on top of a pond. The visible part, is your own programming; the lily pads themselves, but there exists a large, complex layered structure underneath. You typically don't care how it works internally. You don't care about the schools of fish swimming, or the bugs flitting about or layers of muck at the bottom because they don't affect the lily-pads on top. Polymorphism and inheritance are used because the pond uses them, but the part you design, the pads, not so much since that layer on top is generally pretty flat. There are far fewer reasons to make layers of inherited objects beyond what is inherited from the surface of the pond and polymorphism is used without realizing it.
C++ on the other hand is like starting with an empty lot. You need to build a thriving ecosystem of a pond first before you can even get to the point where you're making lily-pads...
Shaggy Hiker
Oct 2nd, 2009, 08:44 AM
C++ on the other hand is like starting with an empty lot. You need to build a thriving ecosystem of a pond first before you can even get to the point where you're making lily-pads...
And if you go too far in any one direction, you end up with a stinking mudhole.
techgnome
Oct 2nd, 2009, 08:56 AM
And if anyone would know about mudholes, it would be shaggy.
I think this just proves that polymorphism isn't really understood as much as we'd think.
My understanding of it is the same as shaggy's. Jenner's explanation is more of (in my opinion) an implementation of the OOP principles. That said, polymorphism is in high use, even if people don't really understand it - or realize it. It's my understanding is that anytime you have an interface that's been implemented by several objects that could be used interchangably, that's polymorphism. So anytime you access a database, as there is a host of interfaces there that the data providers implement. That's what allows us to build Database Connection Factories that return an implementation independent IDbConnection object... and not care if we are connecting SQL, Access, or Oracle.
But then my experiences are coming from VB6 where this type of polymorphism is the only way to come close to any thing close to inheritance.
-tg
Jenner
Oct 2nd, 2009, 10:00 AM
Now I just need to make a fancy 3D GUI plugin for Visual Studio like the Workflow stuff... except everything is graphically represented by pond life: class objects are lily pads, events are insects, event handlers are frogs...
Hey, I bet mendhak would buy it. :afrog:
jmcilhinney
Oct 2nd, 2009, 10:30 AM
Now I just need to make a fancy 3D GUI plugin for Visual Studio like the Workflow stuff... except everything is graphically represented by pond life: class objects are lily pads, events are insects, event handlers are frogs...
Hey, I bet mendhak would buy it. :afrog:I think exceptions should be frogs. ;)
techgnome
Oct 2nd, 2009, 11:00 AM
I agree... then you could catch frogs... and you could catch them based on their type as well.
-tg
Shaggy Hiker
Oct 2nd, 2009, 01:52 PM
Exception handlers should be frogs, as they would be eating bugs.
This thread has certainly got me thinking more about polymorphism. I had totally overlooked the fact that .NET is entirely based on polymorphism. If you aren't using .ToString somewhere in your code, then you are writing either something really strange, something without a user interface, or something incorrect. Since .ToString, and others, are members inherited all the way from Object, which is (sort of) the base of all classes in .NET, then you are always using inheritance, and often using polymorphism.
Another example is the .NET interface, which TG started out on, before wandering off into databases, which is one example. .NET doesn't have traditional multiple inheritance, which is capable of creating a mess quite easily, but offers interfaces as an alternative. An interface is a contract guaranteeing that certain methods and members will exist in any class that implements the interface, but it also has a polymorphic side, because you can instantiate any object as an instance of any interface that it happens to implement. Of course, with that instance you can only call the methods that are part of the interface, but it doesn't make a whit of difference what actual class is being dealt with, only the interface.
If frogs are exceptional, then I, too, aspire to be one someday, but for now I just ramble about polymorphism, which makes me no more than a poly-wag.
(and, in case anybody was wondering, the entire post was just a setup for that pun at the end).
Brent Burgess
Oct 5th, 2009, 12:29 AM
Thanks everyone for your input. Your assistance in with this is greatly appreciated
gep13
Oct 5th, 2009, 01:51 AM
I think exceptions should be frogs. ;)
Ha ha, I had to laugh at this :) :)
chris128
Oct 5th, 2009, 10:04 AM
are members inherited all the way from Object, which is (sort of) the base of all classes in .NET
Why the "sort of" ? I thought even intellisense tells you that Object is the base of every type in the .NET framework?
Shaggy Hiker
Oct 5th, 2009, 01:24 PM
As I wrote it, I got thinking about Integers, which are value types. In general, we think of a variable that holds a value type as containing the actual value, while a variable holding a reference type holds the address of the actual value. If this were actually true, then Integers couldn't be objects...but they are. After a look at IL output, it is clear that an integer variable holds the integer, but it can be boxed into an object, if needed. So an integer doesn't really inherit from type Object, for the sake of efficiency, though it acts as if it does, for the sake of consistency.
Jenner
Oct 5th, 2009, 01:41 PM
Probably at the lowest levels of the framework also for the sake of performance.
jmcilhinney
Oct 5th, 2009, 06:06 PM
So an integer doesn't really inherit from type Object, for the sake of efficiency, though it acts as if it does, for the sake of consistency.There's no acting. All structures, including Int32, are derived from the System.ValueType class, which inherits Object. Absolutely every type in the .NET Framework is derived from the Object class. Just read the documentation for any type and check its inheritance hierarchy. You'll see that every single one of them starts at System.Object.
penagate
Oct 5th, 2009, 06:16 PM
Perhaps this is relevant:
http://msdn.microsoft.com/en-us/library/34yytbws.aspx
Specifically:
Value types are stored as efficiently as primitive types, yet you can call methods on them, including the virtual methods defined on the System.Object and System.ValueType classes, as well as any methods defined on the value type itself.
Shaggy Hiker
Oct 5th, 2009, 07:35 PM
There's no acting. All structures, including Int32, are derived from the System.ValueType class, which inherits Object. Absolutely every type in the .NET Framework is derived from the Object class. Just read the documentation for any type and check its inheritance hierarchy. You'll see that every single one of them starts at System.Object.
I say acting because I looked at IL generated. That code isn't on this system, but the basics were that a locally declared integer is a storage location into which you can assign a literal integer. If you then assign that integer to a variable of type object, there's that call to box. If you use the integer directly as an integer, it never appears to generate anything other than would be expected for the integer to be anything other than a value, which is unlike classes, but I suppose that the two really couldn't look the same in IL, and I could be misunderstanding what is happening there.
jmcilhinney
Oct 5th, 2009, 08:19 PM
I say acting because I looked at IL generated. That code isn't on this system, but the basics were that a locally declared integer is a storage location into which you can assign a literal integer. If you then assign that integer to a variable of type object, there's that call to box. If you use the integer directly as an integer, it never appears to generate anything other than would be expected for the integer to be anything other than a value, which is unlike classes, but I suppose that the two really couldn't look the same in IL, and I could be misunderstanding what is happening there.I suppose it comes down to what's high-level code and what's low-level code. VB doesn't support pointers but pointers are certainly used in the code generated by the compiler. I guess something like Integer.ToString in VB code would look quite different in IL because one is trying to be as easy as possible for the developer while the other is trying to be as efficient as possible for the machine.
Shaggy Hiker
Oct 6th, 2009, 09:47 AM
Exactly. When looking at the IL, it is often difficult to figure out what is happening under the hood, but it is relatively easy to see why it was done the way that it was. It looks like integers are used as actual values for speed, but if needed, they become hidden pointers to objects. By doing that, you might get the best of all worlds, or I might be misinterpreting. It really doesn't matter, because Integer does derive from Object, ultimately, and you will use it as such in programs. The fact that, under the hood, some integers will not really be set up that way to enhance speed, is nothing but a compiler detail which is irrelevant to operations as long as it works right, and it does.
JuggaloBrotha
Oct 6th, 2009, 10:48 AM
I'm curious to know what the code for System.Object looks like. Since everything builds on it, what's in it?
chris128
Oct 6th, 2009, 12:57 PM
<Serializable, ComVisible(True), ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class [Object]
' Methods
Public Overridable Function Equals(ByVal obj As Object) As Boolean
Return Object.InternalEquals(Me, obj)
End Function
Public Shared Function Equals(ByVal objA As Object, ByVal objB As Object) As Boolean
Return ((objA Is objB) OrElse (((Not objA Is Nothing) AndAlso (Not objB Is Nothing)) AndAlso objA.Equals(objB)))
End Function
Private Sub FieldGetter(ByVal typeName As String, ByVal fieldName As String, ByRef val As Object)
val = Me.GetFieldInfo(typeName, fieldName).GetValue(Me)
End Sub
Private Sub FieldSetter(ByVal typeName As String, ByVal fieldName As String, ByVal val As Object)
Dim fieldInfo As FieldInfo = Me.GetFieldInfo(typeName, fieldName)
If fieldInfo.IsInitOnly Then
Throw New FieldAccessException(Environment.GetResourceString("FieldAccess_InitOnly"))
End If
Message.CoerceArg(val, fieldInfo.FieldType)
fieldInfo.SetValue(Me, val)
End Sub
<ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)> _
Protected Overrides Sub Finalize()
End Sub
Private Function GetFieldInfo(ByVal typeName As String, ByVal fieldName As String) As FieldInfo
Dim baseType As Type = Me.GetType
Do While (Not baseType Is Nothing)
If baseType.FullName.Equals(typeName) Then
Exit Do
End If
baseType = baseType.BaseType
Loop
If (baseType Is Nothing) Then
Throw New RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadType"), New Object() { typeName }))
End If
Dim field As FieldInfo = baseType.GetField(fieldName, (BindingFlags.Public Or (BindingFlags.Instance Or BindingFlags.IgnoreCase)))
If (field Is Nothing) Then
Throw New RemotingException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("Remoting_BadField"), New Object() { fieldName, typeName }))
End If
Return field
End Function
Public Overridable Function GetHashCode() As Integer
Return Object.InternalGetHashCode(Me)
End Function
<MethodImpl(MethodImplOptions.InternalCall)> _
Public Function [GetType]() As Type
<MethodImpl(MethodImplOptions.InternalCall)> _
Friend Shared Function InternalEquals(ByVal objA As Object, ByVal objB As Object) As Boolean
<MethodImpl(MethodImplOptions.InternalCall)> _
Friend Shared Function InternalGetHashCode(ByVal obj As Object) As Integer
<MethodImpl(MethodImplOptions.InternalCall)> _
Protected Function MemberwiseClone() As Object
<ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)> _
Public Shared Function ReferenceEquals(ByVal objA As Object, ByVal objB As Object) As Boolean
Return (objA Is objB)
End Function
Public Overridable Function ToString() As String
Return Me.GetType.ToString
End Function
End Class
FunkyDexter
Oct 7th, 2009, 07:00 AM
At the risk of bringing this discussion back onto topic (bad form, I know:rolleyes:) that code of System.Object provides quite a good example of why inheritance can be useful. Look at how minimal it is. And yet everything in the language ultimately derives from it. If you get your inheritance tree right then each class can be very concise. It makes the code in each class very maintainable but it does so at the expenxe of making the object model far more complex.
edit> If frogs truly are exceptions, is it acceptabe to throw them?
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.