Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

Articles / .NET Framework / The Quick and Dirty .NET Guide to C#/VB Object-Oriented Programming

Tip: Looking for answers? Try searching our database.


Article

The Quick and Dirty .NET Guide to C#/VB Object-Oriented Programming

By Dimitrios Markatos   |   Published: 14 July 2005   |   Reader Level:  Beginner


Introduction

Everyone, I'm sure, who has allowed for more than a passing perusal of .NET must be excited at the power of its Framework. Those with a pure programming background and earlier knowledge of pre-.NET technologies have found those to be sorely lacking in the solidity and methodology of a pure OOP (Object-Oriented Programming) environment and or language.

All newcomers to .NET are faced with a new challenge - adjust their thinking process in programming and undoing many bad habits they've acquired when working with a non-OOP environment. Developers with prior ASP/VBScript experience certainly fell upon these habits simply because it never promoted such practices. Therefore, when coming to .NET it can be quite challenging having to rethink or relearn all "programmed" mindsets.

What I will aim at achieving in this article is to get all non-OOP programmers up to speed with this whole brave new world of thinking when programming. Making an allowance for terms such as classes, objects, properties, structs, overloading, inheritance, abstraction, and polymorphism can seem unapproachable to non-seasoned programmers with insufficient OOP awareness. Therefore, my intention is to cut to the chase with all these methodologies and terms, and demonstrate how they all fit together.

Although this article won't be an exhaustive OOP treatise, its objective nevertheless is to present in a quick and dirty manner C#/VB Object-Oriented Programming. Moreover, even though this article may be slightly geared more towards C#, all important VB assessments or similarities are addressed and demonstrated. By the way, keep in mind C# is very case sensitive. Incidentally, don't be put off at the length of this article, a lot of it is simply repeated code examples for both languages.

OOPs

Object Oriented Programming is the concept of programming with objects. What are objects? The computer your seeing this on, the paper you may have printed this on, the printer, your car, TV, etc. are all objects, you get the idea. Moreover, they contain features as well as other objects within them as well. Now the great thing about .NET is that it is itself one huge object-oriented collection. Objects not quite like the ones we'll create and mention, but of a different kind, i.e. Data Objects, System Objects, String Objects, etc. However, unless the objects created are used in concert with other objects they defeat their true nature.

There are two good reasons why you would love programming OOP objects. One is that you have full control over how anyone would use the object you created, and two, encapsulation, in other words your hard earned OOP code is protected and hidden from everyone - systematized together. No one could modify it or change it, certainly anyone not qualified. They simply are available for a specific use, and this is key.

Take for example, if you build one great functional object that does all sorts of math computations, data retrieval and string formatting, and it's going to be used in your company. By not only compiling it, but also by virtue of programming it the OOP way, you protect your intellectual property long after you're gone.

OOP techniques promote the idea of reusability and further allow for all involved in knowing the object's uses, concealing the inner working of your code from inexperienced programmers, simply permitting the object its task alone.

In the old ASP/VB days, you would've had to have created a compiled COM component to realize some of the aforementioned benefits and any gains in performance. However, with .NET this isn't the case since the entire framework is compiled, every page and so forth. Thus building objects in .NET is that and so much more. You have the ability to create new super objects, modularize common code and design lightly coded, cleanly laid out pages. The bottom line is a strong, clean architecture from which stems greater productivity and fewer headaches. No wonder .NET's code-behind, template driven environment espouses all this!

In Object-Oriented Programming, you are dealing with objects. Now, when you embark on any new project you obviously hope in doing the least work possible. Consequently, upon any modifications to your project you don't have to make those changes a thousand times!

Aside from the examples we'll explore how these techniques can apply to everything you are going to work with. Take data access for instance, why not create a data-accessing object with properties whose parameters are the connection string and the query string? In turn, this could be placed throughout your application thus avoiding maintenance headaches and promoting a much cleaner design.

Namespaces

.NET furthers the scope of OOP by compartmentalizing objects within namespaces, as an excellent means of categorizing and personalizing common and related fields, classes, structs or interfaces as a collection, as well as other namespaces known as nested namespaces! When including namespaces in an application, C# uses the "using" keyword to do that, whereas VB specifies "Imports."

This is what facilitates and advances proper reusability and OOP practices. Devoid of this, you would have little structure. Creating a library of common class filled namespaces makes for a well-created application, always having modular components ready for use.

[C#]

namespace JimsEstate {

    public class House { ... }

    public class Car { ... }

    public class Garage { ... }

    }

[VB]

Namespace JimsEstate

    ' Classes and other types of members go here

End Namespace

Here we have the namespace JimsEstate that contains a House, Car and Garage. All are neatly categorized together, and confusion in minimized, thus namespaces. Naming namespaces could easily extend beyond this. JimsEstate could be named JimsEstate.Land.NewYork.LongIsland, if you so choose. That's cool!

At any rate, we'll now look at one of the component types within - classes.

A Class in Objects

Simply put, a class is a created object. In more detail, a class is a reference type (that which stores some type of information) that encapsulates (hides or encloses) and or modularizes (making for flexible, varied use) any amount of methods (functions or subroutines), fields, variables or properties or constructors (object creating function) that classifies data and performs some kind of functionality. Thus, the focal point of OOP is to classify all common functionality and members within a main class that when utilized or instanced in your application, it becomes an object. Object creation is achieved by using the new keyword in your code, as we'll see.

The examples we'll mostly focus will revolve around the House class and its key traits/characteristics. Now if we had a house class and it contained its pertinent house characteristics (fields or variables) it would look something like this. So go ahead and place your preferred language code section in a text file. Next save it as House.cs if using C# or House.vb for VB. This is your source file that you'll compile in the next section.

[C#]

public class House {

    // Its members

    // This is known as initializing a field - see
    // the "Quick Structs" section further down
    // public string HseColor = "gray";

    public string HseBuilder;
    public string HseSize;
    public string HseColor;

    public string Summary() {

        return HseBuilder + " is building a new house that's " + 
             HseSize + " and is painting it " + HseColor;

    }

}

[VB]

Public Class House

    Public HseBuilder As String
    Public HseSize As String
    Public HseColor As String

    Public Function Summary() As String

        Return HseBuilder &" is building a new house that's " & 
             HseSize &" and is painting it " & HseColor

    End Function

End Class

The bits of information we include above in our House blueprint is who the builder is, the house's size and its color. Further enhanced by a summary entailing overall what's included and taking place within our House class.

Therefore, even though this is one template describing one house, it could easily represent and be utilized for any number of houses since each of its public properties values or characteristics may be different each newly created instance of it. In the example above, our diverse information is contained in our public variables or fields that hold what we pass to them in memory. Our variables and method string declaration is known as a data type. In VB the As keyword specifies the data type, in C# the data type precedes the variable name and or method.

The term for using a class, as many times as you wish, each time with different characteristics, is called instantiation or creating an object for use. So the first time the house class is instantiated and assigned it can hold the properties for example, HseSize of "Big" and an HseColor of "Red", and when re-instanced could hold some other very different information. So out of our one House class, we've build two houses all with different characteristics; one class - many uses.

Variables as we've seen have the ability to hold one set value. Class properties unlike their close relatives variables, as we'll examined a little further down, extend the functionality and pretense by allowing you to carry out conditional checking within them preventing any faulty values passed in. Therefore, you can do much, in turn furthering the nature and objective of OOP, as we'll soon examine in the next section.

All we've discussed still needs to be demonstrated real world. Therefore, we'll now build two houses, each with its own particular qualities. So here goes:

A House Building Class

Now that you've already created your house.cs source file, next run the command below to invoke .NET compiler to compile your source file into a DLL we can use, and is located in our root bin folder.

[C#]

csc /t:library /out:c:\inetpub\wwwroot\bin\house.dll house.cs /optimize

[VB]

vbc /t:library /out:c:\inetpub\wwwroot\bin\house.dll house.vb /optimize

Additionally, all code examples throughout are to be compiled in this manner, dependent of course of the language of your choice.

Now that we have the "materials" for our house let's build two houses out of one blueprint if I may. Place the preferred language code below in a .aspx page named House.aspx, then run it in your browser.

[C#]

<%@ Page Language="C#"%>
<html>
<head>
<title>Building a House</title>
</head>

<script language="C#" runat="server">

protected void Page_Load(Object Source, EventArgs E) {

    // Build Jim's house
    House JimsHouse = new House();
    JimsHouse.HseBuilder = "Jim";
    JimsHouse.HseSize = "huge";
    JimsHouse.HseColor = "blue.";

    Response.Write (JimsHouse.Summary() + "<BR><BR>");

    // Clear the object
    JimsHouse = null;

    // Build Lumi's house
    House LumisHouse = new House();
    LumisHouse.HseBuilder = "Lumi";
    LumisHouse.HseSize = "simply breathtaking";
    LumisHouse.HseColor = "however she wants.";

    Response.Write (LumisHouse.Summary());

    // Clear the object
    LumisHouse = null;

    }

</script>
</body>
</html>

[VB]

<%@ Page Language="VB"%>

<script language="VB" runat="server">

Protected Sub Page_Load(Source As Object, E As EventArgs)

    ' Build Jim's house
    Dim JimsHouse As New House()

        With JimsHouse 'VB syntax shortcut

            .HseBuilder = "Jim"
            .HseSize = "huge"
            .HseColor = "blue."

        End With

    Response.Write (JimsHouse.Summary())

    ' Clear the object
    JimsHouse = Nothing

End Sub

</script>

And our results should look like this:

Jim is building a new house that's huge and is painting it blue.

Lumi is building a new house that's simply breathtaking and is painting it however she wants.

To embark on OOP reusability, by using the new keyword we declared and instantiated our object (bring our class to use) - this is know as early binding (the prefered method of dealing with objects). Thus, we write in C# - House JimsHouse = new House() or Dim JimsHouse As New House() in VB; observe C#'s case preference. Essentially, what we're saying here is create a "new House()" object called JimsHouse, that calls our classes default constructor - new House() (which is the same as House.new()), with no parameters, whereas custom constructors utilize parameters.

Then we define or pass its characteristics to the fields in our class. Once we do all this we next call our summary method to return to us our stats. After this, as in every example throughout this article, you must always clear your objects. C# uses the object = null; statement, whereas in VB it's object = Nothing to do this.

So that's it more or less, the basis of object creation and OOP. Not too shabby... but wait.

Let's Up The Variables' Property Value A Bit

Huh? Sorry, I always try for clever wordplay :-) The usage of variables as seen is direct and to the point. But what if we had someone trying to build a house with color's that simply won't do? Well aside from our field assignment, I'll now demonstrate fields kicked up a notch - these being properties that allow you to perform conditional testing to prevent any faulty or unwanted values from being passed in.

Within our properties you deal with two accessors - Get and Set, that work in a read-write fashion. Get retrieves and references any calls from within, for which Set assigns our value when called.

In addition, our summary method now employs our properties as an alternative to our simple variables.

[C#]

public class House {

    //Exposed variables

    public string ShowSize;
    public string HseBuilder;
    public string HseColor;

    //Private properties

    private string ShowBuilder {

        get {return HseBuilder;}
        set {HseBuilder = value;}

    }

    private string ShowColor{

        get {

            if (HseColor == "red"){

                return HseColor + ". But I'll change it to white.";

            }else{

                return HseColor;

            }

        set {HseColor = value;}

    }

     

    public string Summary() {

        return ShowBuilder + " is building a new house that's " + 
            ShowSize + " and is painting it " + ShowColor;

    }

}

[VB]

Public Class House

    Public ShowSize As string
    Public HseBuilder As string
    Public HseColor As String

     

    Private Property ShowBuilder As String

        Get

            return HseBuilder

        End Get

        Set

            HseBuilder = value

        End Set

    End Property

    Private Property ShowColor As String

        Get

            If (HseColor = "red") Then

                Return HseColor & ". But I'll change it to white."

            Else

                Return HseColor

            End If

        End Get

        Set

            HseColor = value

        End Set

    End Property


    Public Function Summary() As String

        Return ShowBuilder & " is building a new house that's " & 
            ShowSize & " and is painting it " & ShowColor

    End Function

End Class

And in our .aspx page we can add, and by now you should've gotten the VB conversion idea as well, the code below:

House MyOtherHouse = new House();
MyOtherHouse.HseBuilder = "Dude";
MyOtherHouse.ShowSize = "looks ok";
MyOtherHouse.HseColor = "red";

Response.Write (MyOtherHouse.Summary());

So after all's said and done our results will look like this:

Dude's building a new house that's looks OK and is painting it red. But I'll change it to white.

The first and last values of our summary method are utilized from our private properties ShowBuilder(), and ShowColor() that incorporates our conditional statement checking that if someone tries to paint our house red, we'll change that to white. The second one is simply from our plain variable - ShowSize. Therefore, we can clearly observe how properties are like super sized variables. Both are accessed the same way, but properties have a little more power over what you permit to take place.

Notice how we use words like public or private in front of our methods, properties or variables? These are what are generally known as access modifiers. In our object, recall how our HseBuilder, HseSize, and HseColor variables are public. With access modifiers we implicitly determine for our object's user what members they will be allowed to be modify or gain access to, their scope in other words.

In our example, the properties that retrieve these assigned public variables and analyze their content are private, and accessible to the class itself and cannot be accessed externally. The true nature of OOP insists on such, that the whole intent is defined by their proper usage, determining their external access allowances.

There are five allowed modifiers or accessibility levels in C# and they consist of:

  • public - Full access is allowed to this
  • private - Accessible from within the calls that contains it
  • internal - Can only be accessed from the current DLL or assembly. Friend in VB.
  • protected - Like private above, and could be access in a class derived from the one it's in
  • protected internal - Can only be accessed from any derived class, itself and like internal - the current DLL it resides in. In VB this would be Protected Friend.

Note: Any time you don't specify any modifiers to a variable, it will default to private. Likewise, on any properties or methods, its modifiers default to public.

Moreover, as far are modifiers are concerned, others exist, for both variable fields and methods, that won't be looked into here, like extern, volatile, sealed, NotInheritable or NotOverridable, etc. In light of the article's objective, .NET's exhaustive documentation would suffice better in clarifying any terms not delved into here. Still, upon reading this guide, any other OOP terms and their supposed uses won't be nearly as challenging to figure out as they may have once been.

Quick Structs

Let's now examine C# structs, or structures as they're referred to in VB. Simply stated, these little bitties act and look just like classes, and utilize all the same kinds of modifiers and elements a class would. You could just think of them as light weight, scaled down classes.

Nevertheless, two caveats though: One, is that they are best suited for smaller data value types under 16 bytes - structures like numbers crunching. Thus, they are used with memory efficiency in mind, as their memory allocation is superior to classes. Two, another key difference in comparison to classes is that they cannot inherit from any other classes as any typical class could, nor could they be a base class either. However, they could implement interfaces though. Also, unlike classes, structs could be instantiated without the new keyword is you so choose. Hmm...

Additionally, classes when instantiated within .NET allocate memory on the heap or .NET's reserved memory space. Whereas structs yield more efficiency when instantiated due to allocation on the stack. Furthermore, it should be noted that passing parameters within structs are done so by value.

A brief word on field initialization and access. Typically, a class field could easily be initialized or preset with a value, as shown:

public class House {
    //This is known as initializing a field
    public string HseColor = "gray";
}

However, this won't work for structs unless the fields are static. Whenever we initialize any fields, they're typically known as instance fields/data, whereas the opposite holds true for fields declared with the static keyword. The main difference between the two is that a static field is accessible anywhere in your application without having to instantiate the class containing it. In VB the equivalent keyword is Shared.

[C#]

public class House or struct House {
    //This is known as initializing a field
    public static HseColor = "gray";
}

[VB]

Public Class House or Structure House

    Public Shared HseColor As String = "gray"

End Structure

Accessing this kind of field is as simple as:

Response.Write (House.HseColor)

Now getting back to our structs. In the House class as shown earlier, changing the "public class House" to "struct House" make's it now a struct like so:

[C#]

struct House {

    // ... Rest of code here

}

[VB]

Structure House

    ' ... Rest of code here

End Structure

Structs are instantiated in your page in the same manner as classes as we've shown. Again, although our listed struct example works fine as is, keep in mind all the aforementioned limitations and key purposes when implementing them in your programs.

Here we'll now quickly overview classes and other members they could contain and or independently behave as:

  • Fields or Variables - A value that is associated with and within an object or class. Declared with modifiers such as public, private, static, shared, const (constants), etc.
  • Constants - A consistent, unchanged value that is associated with an object or class.
  • Properties - Advanced and more adaptable fields, with get and set accessors.
  • Methods - Encapsulated code performing an action or storing some logic.
  • Classes - A reference type that stores and encloses methods (functions or subroutines), fields, variables or properties, constructors, and even other classes that organize data and perform some kind of functionality.
  • Structs - Light weight, scaled down memory efficient classes.
  • Constructors - creates an instance of a class whenever the object is created.
  • Destructors - destroys the instance of a class.
  • Interfaces - Are a set of specifying arrangements with certain characteristics, that when implemented or inherited in a class must abide by. They could contain all mentioned here.
  • Events - Are sent notifying something of actions going to or taking place.
  • Delegates - Are useful for events and for passing one method or function to another as a parameter. Similar to function pointers in C++.
  • Indexers - these allow you to index classes like you would arrays.
  • Enums - Also known as enumerations, these are a series of constant and related values.

Sorry, if I blew your mind with all these terms. It's good to have an idea what they do although you may never use all of them. Nevertheless, I thought a good passing insight was in order.

I won't go into mind numbing detail on every single aspect of OOP, nor everything listed above, as this is not the article's intent. Rather the aim is, as aforementioned, to present the reader with a quick and dirty introduction and synopsis on all more important commonly used principles of OOP, so you can get a good overall idea and grasp on it.

As you now have a decent grasp on the methodology of objects, classes, and properties, we can now press on and claim our .NET inheritance. :-)

Inheritance

Inheritance in OOP is simply taking features from one object and implementing them in another one, like having a new super-duper object, with your new class being a subclass of, and inheriting from, the derived base or main class. Inheritance plays a vital role when attempting to create new custom controls in .NET. For example when creating a Composite Control (made up of multiple server controls) it is formed through inheriting all the features found within the base Class Control.

In any event, let's work with our house class in creating a new class called Location, that will simply show us where our house is located. I'll inherit all the features of our derived house class and then obtain the same output in addition to our location from the code below:

[C#]

public class House {
    // Code same as above
}

public class Location : House {
    public string ShwLocation;
    private string Loc {

        get {return ShwLocation;}
        set {ShwLocation = value;}
    }

    public string ShowStats(){
        return base.Summary() + " It is located in " + Loc;
    }
}

[VB]

'Inheritance syntax in VB

Public Class Location : Inherits House

or alternatively

Public Class Location

    Inherits House

    ' Rest of code here as above

End Class

OK let's examine what's taking place. We've created a new class Location, right in the same .cs source file with our House class, that inherited all the features (fields, methods, etc.) from our derived base class House. We set up our public ShwLocation field and our private Loc property to get and set our value. Next we create a new method ShowStats() and within it use base.Summary() to pull in the Summary() method's results from our inherited main class, and thus our new ShowStats() method's combined results as seen below.

And our .NET page now has this:

Location oHouse = new Location();
oHouse.HseBuilder = "Peter";
oHouse.HseSize = "looks OK";
oHouse.HseColor = "red";
oHouse.ShwLocation = "New York";

Response.Write (oHouse.ShowStats());

Here we create a new Location object and we use fields that are not in our Location object, but are in our House object! We've inherited all its features and added the ShwLocation only, and this is one not found in our base class but our new subclass. That's inheritance.

Your result:

Peter built a new house that's looks OK and is painting it red. But I'll change it to white. It is located in New York.

Pretty nice. Now wouldn't it be even nicer still if we could inherit from multiple classes? Sure would, but only C++ gives you that luxury as of late. However, interfaces, as we'll look over a little later, are just that luxury to make up for it.

Lest we become Abstracted

Huh? I thought I'd be innovative. Well, let's now look into another type of class, although nothing new to VB - Abstract classes. These are classes that act like generic, nonfunctional templates, on the surface similar to Interfaces, for more specialized classes that could contain both non-abstract and abstract methods or properties, etc., intended for a new, more robust class. Their selling point is their ability to remain silent, minimally predisposed and standing by ready to be redefined and implemented once inherited, and further help in pinpointing any runtime compilation or implementation errors.

Both abstract classes and interfaces cannot be instantiated. As we'll examine later, interfaces are contracts for other classes behavior with no set functionality. Although similar in concept, abstract classes however can contain abstract functionality (methods, etc.), as well as typical non-abstract methods.

Therefore, creating one take's place when you use the keyword abstract as you declare the class. When inheriting an abstract class in a regular or non-abstract class, you need to override all methods or properties before implementing, unless they are not abstract members. When implementing non-abstract members inherited from an abstract class in a non-abstract class you need to use the keyword Shadows in VB and new in C#. This behavior is known as method hiding.

Abstract classes are more useful when multiple versions of a component are required and for more larger sets of code, as opposed to an interface with its purpose aimed at smaller, unrelated bits of functionality. Remember the Class Vs Struct comparison? Kind of like that. Moreover, abstract classes could also inherit from non-abstract classes and even interfaces!

This is a basis for polymorphism as we'll later examine. However not quite in this context, since we're not altering it base form to another form.

Below we create an abstract House class with abstract members. Upon creating a new non-abstract class we inherit our abstract class and implement its features by overriding them, like so:

[C#]

public abstract class House
{

    public abstract string ShowColor();
    public abstract string ShowSize();

    //Non-Abstract method
    public string Whatever(){

        return "Anything";

    }

}

public class HouseStats : House
{

    public override string ShowColor()
    {

        return "blue";

    }

    public override string ShowSize()
    {

        return "small";

    }

    //Method Hiding
    public new string Whatever(){

        return "New Value";

    }


}

[VB]

Public MustInherit Class House

    MustOverride Function ShowColor()

    'Non-Abstract Method
    Public Function Whatever() As String

        Return "Anything"

    End Function

End Class


Public Class HouseStats : Inherits House

    Overrides Function ShowColor()

        Return "blue"

    End Function

    Public Shadows Function Whatever() As String

        Return "New Value"

    End Function

End Class

As you can tell, the C# keyword abstract translated to MustInherit in VB, in turn defining these types of classes and non-instantiable base classes.

Consequently, because of its design, abstract classes, and interfaces as we'll later examine, work well avoiding run-time bugs associated with derived classes, due to their nature in being overridden when used.

Parameters

The concept of passing parameters is nothing new to OOP, and certainly not an incredibly difficult concept to grasp, since the same techniques were used when programming ASP/VB parameterized subroutines and functions. And what exactly are parameters? Values.

Shortly, as we explore Overloading, you'll simultaneously gain knowledge of this concept as well, if you already didn't.

Method Overloading

Method Overloading or Overloading is the means of re-implementing a method with the same name numerous times, providing its signatures (or number of parameter and or parameter reference types) are different.

To demonstrate, we'll now overload our ShowStats() method (taken from the Inheritance section code example) two different ways. Right after the default ShowStats method you can create overloaded methods, ready for implementation depending on your purpose like so:

 public string ShowStats(string StartTxt){

    return base.Summary() + " - " + StartTxt + " it is located in " + Loc;

}

public object ShowStats(string StartTxt, string EndTxt){

    return base.Summary() + " - " + StartTxt + 
        " it is located in " + Loc + " - " + EndTxt;

}

Our default ShowStats() method as noted before is the standard non-overloaded method. Above however, we've added an additional two methods, both overloading our default method. The first one a string method, accepts only one parameter StartTxt, thus its signature distinguishes it from its predecessor. The second pushes further by being an object method with two parameters, StartTxt and EndTxt. Both retrieving Loc from before as well.

And in our .aspx page we implement it, in addition to the way we did before, like this:

//Overloaded method 1
Response.Write (oHouse.ShowStats("I think") + "<BR><BR>");

//Overloaded method 2
Response.Write (oHouse.ShowStats("I'm sure","That's cool!") + "<BR><BR>");

Same name, different signatures thus overloading, and our results:

[Overloaded method 1]
Peter built a new house that's looks OK and is painting it red. But I'll change it to white. - I think it is located in New York

[Overloaded method 2]
Peter built a new house that's looks OK and is painting it red. But I'll change it to white. - I'm sure it is located in New York - That's cool!

Interfaces

Back in our section on abstract classes we dealt with interfaces in comparison. We briefly explained that they look like classes but they don't get instantiated in your page as would a typical class. Reason for this is that they are used or inherited by other classes for a particular functionality as a contract. In other words, they provide specs or behaviors for other classes as to their use or redefinition rather than their direct implementation. Incidentally, interfaces are C#'s answer to C++'s multiple inheritance.

Now to create an interface we'd declare an interface with the interface keyword and specify the interface name. Good naming convention suggests a capital "I" before the interface name to avoid any confusion and to confirm a naming structure.

Key points:

  • As a rule, interfaces are always, by default public, as are their members.
  • Interfaces could contain the following members: methods, properties and events
  • All the members within an interfaces, whether a method or field, cannot themselves contain anything, they would need to be empty without any body text.
  • Interfaces themselves could even inherit other interfaces, and without having to implementing all its methods, unlike classes, which have to!
  • Both classes as well as structs could inherit multiple interfaces.

In addition, whatever methods or properties the interfaces contain, they would all have to be implemented upon inheriting them in your new class. Still if you prefer you can conditionally check if an actual interface is valid from within by using the is operator.

Furthermore, implementing and redefining methods and properties of an interface can be done two ways: implicitly, that we do, via our publicly and or virtually declared members, or explicitly, which are referenced directly via the interface name.

Below, the C# examples are no different than before, however, the VB implementation requires some attention. Multiple Inheritance as we've touched upon in light of interfaces, can be accomplished this way:

[C#]

interface IAllStats
{

    int ShowSquareFeet { get; } //Interface property

    void ShowOwner(); //Interface method


}

interface IAllStats2 {

    string OwnerName { get; set; } //Interface property

    void ShowLocation(); //Interface method

}

//Multiple Inheritance feature of Interfaces
public class UseBothInterfaces : IAllStats, IAllStats2
{

    // Field for interface property

    private string _OwnerName;


    // Property implementation

    public int ShowSquareFeet {

        get { return 3600; } //Read only value

    }

    public string OwnerName { //Getter and Setter property

        get { return _OwnerName; }

        set { _OwnerName = value; }

    }

    // ShowOwner() method implemented, assigning OwnerName
    public void ShowOwner() { OwnerName = "Pete"; }

    public void ShowLocation() { } // ShowLocation() method implemented


    public object ShowStats(){

        //ShowOwner(); // Method called - overrides property

        return OwnerName + " owns a house that's " + 
            ShowSquareFeet + " square feet";

    }


}

[VB]

Interface IAllStats
    'This property is only read only
    ReadOnly Property ShowSquareFeet() As Integer

    Function ShowOwner() As String

End Interface

Interface IAllStats2

    Property OwnerName() As String

    Function ShowLocation() As String

End Interface

'Multiple Inheritance feature of Interfaces
Public Class UseBothInterfaces : Implements IAllStats, IAllStats2

    Private _OwnerName As String

    Public ReadOnly Property ShowSquareFeet As Integer
        Implements IAllStats.ShowSquareFeet

        Get
            Return 3600 'Read only value
        End Get

    End Property

    'Getter and Setter property
    Property OwnerName As String Implements IAllStats2.OwnerName

        Get
            Return _OwnerName
        End Get

        Set
            _OwnerName = value
        End Set

    End Property

    Public Function ShowOwner() As String Implements IAllStats.ShowOwner

        OwnerName = "Pete"

    End Function

    Public Function ShowLocation() As String
            Implements IAllStats2.ShowLocation
        ' ShowLocation() method implemented
    End Function


    Public Function ShowStats() As Object

        ' ShowOwner() ' Method called - overrides property - See results below

        Return OwnerName & " owns a house that's " & 
            ShowSquareFeet & " square feet"
    End Function

End Class

Implementing this is as easy as this:

[C#]

UseBothInterfaces StatsInter = new UseBothInterfaces();
StatsInter.OwnerName = "Jim";
Response.Write (StatsInter.ShowStats());

[VB]

Dim StatsInter As UseBothInterfaces = New UseBothInterfaces()
StatsInter.OwnerName = "Jim"
Response.Write (StatsInter.ShowStats())

OK, now what took place? Well, we created two interfaces that include both method and properties (both a standard string property and readonly integer property). Next we set up our class that inherits multiple interfaces, and we then begin defining their members from our two interface templates.

In our above .aspx page code, we instance our class UseBothInterfaces(), and proceed to assign our object's OwnerName() method a value, and then write out our results. Our ShowStats() method is set up to do two things. Call, thus implement, the ShowOwner() method along with its code (which overwrites Jim with Pete), and or return to us the OwnerName that was set from our page's object instantiation, alongside our ShowSquareFeet() method's measurements that were internally already assigned.

Therefore, working with interfaces offers us the ability and has demonstrated how we could inherit and implement multiple interfaces in a class, assign and retrieve property values, implement methods and return results that can be accomplished either internally or externally through our web page from our two contracts. In our example we decided to implement both interfaces, and all define all their members.

And our results:

[Results without ShowOwner() method implemented]

Jim owns a house that's 3600 square feet

[Results with ShowOwner() method implemented]

Pete owns a house that's 3600 square feet

Another point to note is that our VB code in comparison to C# requires the Implements keyword referencing the implemented interface and method. Again upon implementing an interface, you must implement all the members of that interface, unlike abstract classes that do not support multiple inheritance, but are allowed to choose what members you wish to implement, as long as you specify to the contrary.

Quick observation: Creating an instance of the class inheriting multiple interfaces is demonstrate above in our BothInterfaces() method. Now notice that we create an instance and we could reference any class that implements any interface. Moreover, interfaces due to their insistent complete implemenation schema could go a long way in preventing runtime bugs.

As we'll explore polymorphism, you'll discover instantiation of a different kind, that applies to interfaces as well.

Finally Polymorphism

Polymorphism is really pretty easy to understand. First off, it is derived from two Greek words "Poly" meaning many and "Morphism" means forms or shapes. In OOP this is taken to mean how one object is used as if it's another different object altogether. Key factors for polymorphism to take place are that the methods involved are overridable. Furthermore, upon polymorphism via inheritance, you are able to construct a uniquely new object based on a commonly derived method.

Any polymorphic methods in C# are declared with the keyword virtual or abstract, and the method overriding this specifies override. In VB you're dealing with Inheritable/Overridable methods. Contrary to overloading, overriding must include the identical features, including all the signatures (number of parameters) as the derived base class method.

[C#]

public class House
{
    public virtual string GetStatistics()
    {
        return ("My House is spacious");
    }
}

public class GuestHouse : House
{
    public override string GetStatistics()
    {
        return ("My House now a Guesthouse is roomy");
    }
}

public class Garage : House
{
    public override string GetStatistics()
    {
        return ("My House now a Garage is wide");
    }
}

[VB]

MustInherit Public Class House
    Public MustOverride Function GetStatistics() As String
        Return ("My House is spacious")
    End Function
End Class

Public Class Guesthouse : Inherits House
    Public Overrides Function GetStatistics() As String
        Return ("My House now a Guesthouse is roomy")
    End Function
End Class

Public Class Garage : Inherits House
    Public Overrides Function GetStatistics() As String
        Return ("My House now a Garage is wide")
    End Function
End Class

What was accomplished here through abstract polymorphism is that we overrode and modified the GetStatistics's return value. The other concept of Polymorphism - Inheritance-Based Polymorphism, work much along the same lines.

Our code to instantiate them is:

[C#]

House myHouse = new House();
House myGuestHse = new Guesthouse();
House myGarage = new Garage();


Response.Write(myHouse.GetStatistics() + "<BR>");
Response.Write(myGuestHse.GetStatistics() + "<BR>");
Response.Write(myGarage.GetStatistics());

[VB]

Dim myHouse As House = New House()
Dim myGuestHouse As House = New Guesthouse()
Dim myGarage As House = New Garage()

Response.Write(myHouse.GetStatistics() & "<BR>")
Response.Write(myGuestHouse.GetStatistics() & "<BR>")
Response.Write(myGarage.GetStatistics() & "<BR>")

And our results are:

My House is spacious
My House now a Guesthouse is roomy
My House now a Garage is wide

So even though I declared my variables as a House, through polymorphism my House object takes on a different type and gets transformed into myGuestHouse and even myGarage! Think of the possibilities.

Phew! Not too bad. Well take heart that you have learned a great deal of OOP concepts and now should find it less cumbersome.

Conclusion

In conclusion, beyond all we've touched upon, OOP can be quite extensive in its depth and conceptual methodologies. There is far more that can be learned, including everything from sealed and non-inheritable classes to delegates and events and so forth, to say the least. The intricacy of OOP unquestionably extends far beyond what was described here.

Still, the foundation we've set forth I hope is an excellent start and overview of OOP for you. There are hundreds of great resources online that would allow you a deeper look into the illimitable complexities and structures of OOP. Yet, learning all these concepts is best accomplished like most things in development, having something to make use of them in and performing real-world work.

In close, my objective here was to introduce a direct and to the point outline of OOP that should now have given you a firm place to stand on from which you now could plan your next move on the road to object-oriented application development. </>

Until next time, Happy .NETing!


About Dimitrios Markatos

Dimitrios, or Jimmy as his friends call him, is an independent .NET architect who specializes in Microsoft Technologies for creating high-performance and scalable data-driven enterprise Web and desktop applications. Till now Jimmy has authored nearly two dozen .NET articles, published on Dot Net Junkies, 4 Guys From Rolla, Sitepoint, Developer Fusion, MSDN Academic Alliance, Developers.NET, and The Official Microsoft ASP.NET Site, covering various advanced and unique techniques on .NET.


 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage




©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.