Showing posts with label Object Oriented Programming. Show all posts
Showing posts with label Object Oriented Programming. Show all posts

Wednesday, March 14, 2012

Polymorphism via Interfaces - II

In previous post we discussed polymorphism via interface. In this post we will expand it to demonstrate how you can implement more than one interface in a class and how you can pass an object that implements the interface to another method and have it do something.

In the example below, we declared two interfaces - IPrintable and IUserType and then created three classes that will implement these two interfaces. We then declared another static class with a static method that can accept the object and do something with it.

IPrintable Interface
Paste your text here.using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    interface IPrintable
    {
        void print();
    }
}


IUserType Interface

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    interface iUserType
    {
        void userType();
    }
}


First Class - Implementing both Interfaces

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    class Employee:IPrintable,iUserType
    {
        public string Name { get; set; }
        public bool IsFullTime { get; set; }
        
        public void print()
        {
            Console.WriteLine("Name:={0},FullTime={1}", Name, IsFullTime);
        }
        public void userType()
        {
            Console.WriteLine("Employee");
        }
    }
}


Second Class - Implementing both Interfaces
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    class Instructor :IPrintable,iUserType
    {
        public string Name { get; set; }
        public string SeniorityLevel { get; set; }
        public bool IsTenured { get; set; }

        public void print()
        {
            Console.WriteLine("Name:={0},SeniorityLevel={1},Tenured={2}", 
                              Name, SeniorityLevel, IsTenured);
        }
        public void userType()
        {
            Console.WriteLine("Instructor");
        }
    }
}



Third Class - Implementing both Intefaces
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    class Student : IPrintable,iUserType
    {
        public string Name { get; set; }
        public string StudentID { get; set; }
        public String GradeLevel { get; set; }

        public void print()
        {
            Console.WriteLine("Name:={0},GradeLevel={1},StudentID={2}", 
                               Name, GradeLevel, StudentID);
        }
        public void userType()
        {
            Console.WriteLine("Student");
        }
    }
}



Static Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    static class Print
    {
        public static void Printout(IPrintable printableObject)
        {
            printableObject.print();
        }
        public static void UserType(iUserType UserType)
        {
            UserType.userType();
        }
    }
}





Calling Method
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Interfaces
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee emp = new Employee();
            emp.Name = "1st Employee";
            emp.IsFullTime = true;

            Print.Printout(emp);
            Print.UserType(emp);
            Console.WriteLine(Environment.NewLine);

            Instructor ins = new Instructor();
            ins.Name = "1st Instructor";
            ins.IsTenured = true;

            Print.Printout(ins);
            Print.UserType(ins);
            Console.WriteLine(Environment.NewLine);

            Student std = new Student();
            std.Name = "1st Student";
            std.StudentID = "123456";
            std.GradeLevel = "Junior";

            Print.Printout(std);
            Print.UserType(std);
            Console.Read();

        }
    }
}




In the example above, three classes implement IPrintable and IUserType interface and the Main method calls static methods Printout and UserType declared in Print static class, passing the object.

Notice the Printout and UserType static methods call Print and userType that are implemented in the passed objects.

The only reason you can be sure that regardless of the object type you pass to the static Print and UserType method, the code will work just fine is because any class that implements an interface is guaranteed to implement all the signatures that are declared in the interface. An interface is a contract and any class implementing an interface must implement all its methods.

Saturday, March 10, 2012

Polymorphism via Interfaces

In previous post we discussed polymorphism via abstraction. Today, we will discuss polymorphism via interfaces. The concept is similar except that here you declare an interface with a signature which you will then implement in one or more derived class

Consider a base employee interface with signature and then you create a full time and part time employee classes that inherit from this interface.

Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    interface iEmployee
    {
        
        void PrintEmployee();
        
    }
}


Derived Class 1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    class FullTime : iEmployee
    {
        public int employeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EmployeeType { get; set; }
        public string OverTime { get; set; }
        public string VacationDays { get; set; }

        // a method signature declared in interface is implemented here
        void iEmployee.PrintEmployee()           {
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}",
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }
    }
}


Derived Class 2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
     class PartTime:iEmployee
    {
        public int employeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EmployeeType { get; set; }
        public string OverTime { get; set; }
        public string VacationDays {get;set;}
  
       // a method signature declared in interface is implemented here
        void iEmployee.PrintEmployee() 
        {
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}", 
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }
      public void Print()
        {
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}", 
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }

    }
}



As you can see, a method signature "PrintEmployee" is implemented in derived classes. A class can implement one or more interfaces and must implement the method signatures declared in each interface.

You can use the above classes as follows. Notice since the method PrintEmployee is declared in an interface, you cannot use it like you would if it was declared in a class. Since both PartTime and FullTime implement iEmployee, you should be able to cast the classes to iEmployee and then call PrintEmployee method.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    class Program
    {
        static void Main(string[] args)
        {
            PartTime Emp1 = new PartTime();
            //notice this property is declared in base class but available in derived class.
            Emp1.employeeID = 1234;
            Emp1.FirstName = "Part Time";
            //notice this property is declared in base class but available in derived class.
            Emp1.LastName = "Employee";
            Emp1.EmployeeType = "Part Time";

            iEmployee Emp = Emp1;
            Emp.PrintEmployee();

            FullTime Emp2 = new FullTime();
            //notice this property is declared in base class but available in derived class.
            Emp2.employeeID = 5678;
            Emp2.FirstName = "Full Time";
            //notice this property is declared in base class but available in derived class.
            Emp2.LastName = "Employee";
            Emp2.EmployeeType = "Full Time";

            Emp = Emp2;
            Emp.PrintEmployee();

            Console.ReadLine();
        }
    }
}

This is a basic concept but interfaces could be confusing. Hope this helps you understand the concept.

Thank you.



Tuesday, March 6, 2012

Polymorphism Via Inheritance

In one of my post  we discussed four basic tenets of Object Oriented Programming. Polymorphism is one of the key fundamental of OOP. Polymorphism means many forms - in other words an object can take on many forms based on its implementation details. There are several ways you can implement polymorphism such as via inheritance, via interface or via abstract classes. We will discuss polymorphism via inheritance today.

Consider a base employee class with few properties and then you create a full time and part time employee classes that inherit from the employee class.

Basically you are declaring a base class with some parameters/features and then extending it into the derived classes by either modifying the base functionality or adding class specific features.

Base Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    class Employee
    {
        public int employeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public virtual void PrintEmployee()
        {
            Console.WriteLine("EmployeeID={0},Employee Name={1}, {2}", 
                              employeeID,LastName, FirstName);
            Console.WriteLine(Environment.NewLine);
        }
    }
}


Derived Class 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    class FullTime:Employee
    {
        public string EmployeeType { get; set; }
        public string OverTime { get; set; }
        public string VacationDays {get;set;}
  
       public override void PrintEmployee()
        {
            base.PrintEmployee();
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}", 
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }
    }
}



Derived Class 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymorphism
{
    class PartTime:Employee
    {
        public string EmployeeType { get; set; }
        public string OverTime { get; set; }
        public string VacationDays {get;set;}
  
       public override void PrintEmployee()
        {
            base.PrintEmployee();
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}", 
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }
    }
}



As you can see, base virtual method "PrintEmployee" is extended in derived classes. Properties declared in the base class are available to derived classes.

If you want to extend a method like we did here, you must declare the method with keyword "virtual" in base class and use keyword "override" in derived class.

This is a very basic concept but could be confusing for someone new to object oriented programming paradigm. Hope this helps you understand the concept.

In future posts we will discuss polymorphism via interface and abstract classes.

Thank you.



Thursday, March 1, 2012

C# Delegates

The concept of delegates is somewhat confusing and developers often wonder why we need them and where would we use delegates? We will discuss delegates with an example and hopefully clarify potential uses for them.

Consider a list object of a specific type. You can encapsulate one or more objects of the same type in this list and pass the list to other methods to read and do something with those objects. Delegates are similar in nature except that they encapsulate references to the methods of an object.

A delegate can encapsulate any method as long as method signatures are same as those of delegates. Use can then pass around those delegates or use them just as you would use the method encapsulated in those delegates.

Let's consider an example.

In this example, we will create a class which will take the hourly pay, hours worked, tax rate and return weekly pay as well as tax.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class CalculateWeeklyPay
    {
        private double _hourlypay;
        private double _hours;
        private double _overtimerate;
        private double _taxrate;

   public CalculateWeeklyPay(double hourlypay, double hours, 
                             double overtime, double taxrate)
        {
            _hourlypay = hourlypay;
            _hours = hours;
            _overtimerate = overtime;
            _taxrate = taxrate;
        }
        public double calculateTax()
        {
            double grosspay = calculateGrossPay();
            double tax = grosspay * ((double)_taxrate / 100);
            return tax;
        }
  public double calculatePay(double hourlypay, double hours, 
                             double overtime, double taxrate)
        {
            _hourlypay = hourlypay;
            _hours = hours;
            _overtimerate = overtime;
            _taxrate = taxrate; 
            return calculatepay();
        }
        public double calculatePay()
        {
            return calculatepay();
         }
        private double calculatepay()
        {
            double grosspay = calculateGrossPay();
            double netpay = grosspay-(grosspay * ((double)_taxrate / 100));
            return netpay;
        }
        private double calculateGrossPay()
        {
            double basepay;
            double overtimepay = 0;
            double grosspay;
            
            if (_hours > 40)
            {
                overtimepay = (_hours - 40) * (_hourlypay * _overtimerate);
                basepay = 40 * _hourlypay;
            }
            else
            {
                basepay = _hours * _hourlypay;
            }
            grosspay = basepay + overtimepay;
            return grosspay;
        }
     }
}

Now, lets create a console app, which will instantiate this object and then return the weekly pay and tax. We will create two delegates. One delegate will work with two methods (CalculatePay and CalculateTax) and another delegate will work with overloaded CalculatePay method.

Note, a delegate must have the same signature and same return type of the referenced method that it will encapsulate.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        //declared two deletages, one for each method
        //(since they have different signatures, you can't use same delegate)
        //also note return type for the delegate 
        //must be same as the return type of the signature.
        public delegate double delegate1();
        public delegate double delegate2(double hourlypay, double hours, 
                                         double overtime, double taxrate);
      
           
        static void Main(string[] args)
        {
            double hourlyPay = 7.50;
            double hours = 45;
            double overtimeRate = 1.5;
            double taxRate = 5;
          CalculateWeeklyPay calculatepay = new CalculateWeeklyPay(hourlyPay, 
                                                 hours, overtimeRate, taxRate);
            //you must instantiate a delegate
            delegate1 firstDelegate = new delegate1(calculatepay.calculatePay);
            Console.WriteLine("First Delegate {0} ", firstDelegate());
            Console.WriteLine(Environment.NewLine);
            //you can use same delegate for another method as long as 
            //its signatures and return type are same
            delegate1 anotherDelegate = new delegate1(calculatepay.calculateTax);
            Console.WriteLine("First Delegate Different Use {0} ", 
                              anotherDelegate());
            Console.WriteLine(Environment.NewLine);
            //let's use second delegate
            delegate2 secondDelegate = new delegate2(calculatepay.calculatePay);
            //you must pass the parameters that this delegate is expecting, 
            //otherwise a runtime error will occur
            Console.WriteLine("Second Delegate{0} ", 
                       secondDelegate(hourlyPay, hours, overtimeRate, taxRate));
            Console.WriteLine(Environment.NewLine);
            Console.Read();
        }
    }
}


One of the main use of delegates is in events. Suppose you want an object to notify another object when something happens. For example, a stock market object should fire an event when stock price changes for a stock you are watching. Another object (listener) can capture this event and do something with it instead of constantly polling the stock market object to see if the price has changed. In C#, you need delegates to create events such as this.

We will discuss events in future posts.

Thank you.

Wednesday, February 22, 2012

Enumerations

Recall my previous post about value types vs. reference types. Just to recap, simple data types such as int, float, double, decimal etc. are value types while complex types such as objects, strings are reference types. There are two exceptions to this concept. Structures and Enumerations. Despite being complex types, Structures and Enumerators are value types and hence they are stored on stack as opposed to heap.

In this post we will discuss enumerations and we will cover structures in next post.

Enumerations
Enumerations allow you to group constants at one place in a name-value pair format and allows you to access the values using strongly typed names. The key difference between an array list or a dictionary object and enumeration is that the arraylist / dictionary is a reference type and hence stored on heap while enumerators are value types and are stored on stack. Use of enumerators also allow you to keep the constants at one place hence being able to easily manage them and makes your code easier to read.

The underlying datatype for an enumeration can only be of an integral type. It can be of any integral type except "Char". The default type is int.

An enumeration is declared using enum keyword. Lets see an example.

enum Color
{
   Red,
   Blue,
   Green,
   Orange
}

If you don't specify the value, underlying integer datatype is assumed and the value is assigned from 0 onwards. For example in above example, Red=0, Blue=1, Green=2, Orange=3.

You can explicitly assign any value to each type, for example

enum Color
{
   Red = 8,
   Blue = 9,
   Green  =12,
   Orange=20
}


As I mentioned previously, underlying datatype for an enum can be any integral type except char. Following datatypes are supported 
  • byte, sbyte, short, ushort, int, uint, long or ulong.
To use any other datatype except int, declare it as follows...


enum Color : byte
{
   Red ,
   Blue ,
   Green ,
   Orange
}

Usage
Apart from keeping the constants at one place, it also makes code easier to read. See the following example...

 public class EnumTest
 {
   static void Main()
   {
      Console.WriteLine("Red={0}", Color.Red);
      Console.WriteLine("Blue={0}", Color.Blue);
   }
}

That's all there is to it. It is a relatively simple concept but when used appropriately promotes cleaner and readable code.

Thank you.

Saturday, February 18, 2012

Shallow Vs. Deep Copy


Although the concept is relatively simple, I have seen many developers struggle with the concept of shallow vs. deep copy.

First, both shallow and deep copy involves copying an object to another object. The difference lies in what is copied when the object contains a variable of reference type such as an instance of another object or an array / arraylist.

Shallow Copy
When you copy an object into another object, all the non-static members are copied from the original object to its copy. All the variables of value type are copied, but if the object contains variables of reference type, then only the reference is copied but the actual referred object is not copied. So, both the actual object and its copy refer the same instance of the object that is being referenced.

For example, consider the following class, which references another object

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace ShallowDeep
{
[Serializable]
public class Employee
{
    private string _name;
    private int _age;
    private Address _empAddress; // reference to another class, hence a reference type.
    public String Name
     {
        get { return _name; }
        set { _name = value; }
     }
    public int Age
     {
        get { return _age; }
        set { _age = value; }
     }
    public Address EmpAddress
     {
        get { return _empAddress; }
        set { _empAddress = value; }
     }
    //method to create a shallow copy
    public Employee CopyShallow(Employee EmpCopy)
       {
         //use MemberWiseClone to create a shallow copy
         return (Employee)EmpCopy.MemberwiseClone();
       }
    //Method to clear a deep copy
    public Employee CopyDeep(Employee EmpDeepCopy)
       {
          MemoryStream ms = new MemoryStream();
          BinaryFormatter bf = new BinaryFormatter();
          bf.Serialize(ms, EmpDeepCopy);
          ms.Seek(0, SeekOrigin.Begin);
          Employee result = (Employee)bf.Deserialize(ms);
          ms.Close();
          return result;
       }
   }
 
 }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ShallowDeep
{
    public class Address
    {
        private String _mailingAddress;

        //constructor
        public Address(string MailingAddress)
        {
           _mailingAddress = MailingAddress;
        }
        public String EmpAddress
        {
            get{return _mailingAddress ;}
            set{ _mailingAddress =value;}
        }
     }
 }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ShallowDeep
{
class Program
{
    static void Main(string[] args)
    {
       //Shallow Copy
       //create an instance of Employee Class
       Employee oEmployee = new Employee();
       oEmployee.Name="Test User";
       oEmployee.Age = 30;
       Address oAddress = new Address("123 Ross Street, Atlanta, GA, 12345");
       oEmployee.EmpAddress=oAddress;
       //Now perform a shallow copy
       Employee oEmployee2 = oEmployee.CopyShallow(oEmployee);
      //Now lets do the following
      oEmployee2.Age = 25;
      oAddress.EmpAddress = "303 Peachtree Road, Atlanta, GA, 30032";
      //Check the value of oEmployee2.EmpAddress.
     int empOriginalAge = oEmployee.Age;
     int empCopyAge = oEmployee2.Age;
     Address EmpOriginalAddr = oEmployee.EmpAddress;
     Address EmpCopyAddr = oEmployee2.EmpAddress;
   }
  }
}


Notice the value of empOriginalAge=30 but the value of empCopyAge=25, but the value of EmpOriginalAddr and EmpCopyAddre is same i.e. "303 Peachtree Road, Atlanta, GA, 30032"


Deep Copy
To be able to deep copy an object, it must be serializable. Difference between a shallow and deep copy is that in addition to a bit by bit copy of a value object, deep copy also copies the reference object, instead of just copying only the reference to the object.

Let's use the same example as above, but instead use DeepCopy method.

Add the follow snippet to the method above.
//Deep Copy
//create an instance of Employee Class
Employee oEmployeeDeep = new Employee();
oEmployeeDeep.Name="Test User";
oEmployeeDeep.Age = 30;
Address oAddress2 = new Address("123 Ross Street, Atlanta, GA, 12345");
oEmployeeDeep.EmpAddress=oAddress2;
//Now perform a deep copy
Employee oEmployeeDeep2 = oEmployee.CopyDeep(oEmployeeDeep);
oEmployeeDeep2.Age = 25;
oAddress2.EmpAddress = "303 Peachtree Road, Atlanta, GA, 30032";
//Check the value of oEmployee2.EmpAddress.
Address EmpAddress = oEmployeeDeep2.EmpAddress;



The value of the EmpAddress will still be "123 Ross Street, Atlanta, GA, 12345".

Hope this helps clarify the difference between a shallow and deep copy. Remember, shallow sopy is done via MemberWiseClone(), while a deep copy is performed by serializing the object, hence the class must be serializable.

Just remember, the key difference is that in shallow copy only a reference to any reference type variable  is copied while in deep copy, the referenced object itself is copied.

Thank you and as always, your comments are appreciated.


Wednesday, February 15, 2012

Boxing and Unboxing

In previous post we discussed the concept of value types vs. reference types and how two are different. Today we will discuss Boxing and Unboxing.

Boxing and Unboxing
Boxing is the process of converting a value type to a reference type. If you recall from my previous post about Value Types vs. Reference Types, the value types are stored on a stack while the reference types are stored on heap and a pointer to the reference type is stored on the stack.

Let's assume you have the following method..


public void Add(object obj, object obj2)
        {
            if (obj.GetType()  == typeof(string) && obj2.GetType() == typeof(string))
                {
                //do something...
                }
            else if (obj.GetType() == typeof(int) && obj2.GetType() ==typeof(int))
                {
                //do something...
                }
        }

 
When you call this method and pass an integer or some other value type variable, it is first boxed, i.e. converted to a reference type and then it is unboxed i.e. converted back to value type before it is used. Boxing is implicit but unboxing is explicit i.e. you must cast the boxed variable back into the value type before you can use it.

Note: The code above is for illustration only and you should try to avoid boxing/unboxing for obvious performance reasons.

Another example of implicit boxing is in the use of an arraylist. For example,

ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);

Recall that an arraylist is a reference type. When you add an integer to the arraylist, it is then boxed i.e. converted to a reference type and then added to the arraylist. When you need to use the value assigned to this arraylist, it must be unboxed.

int i = (int)(list(0);



Monday, February 13, 2012

Difference between an Interface and an Abstract class

All Programming Fundamentals! It is rather easy to articulate the difference between the two, but I have seen people stumble when asked to explain it. So today, we will try to cover this topic and provide an example to clarify some of the key differences.

 Abstract Class
An Abstract Class is just like any other class with a few key differences. As we discussed in my previous post, non-static classes can be instantiated except with one type of class - an Abstract Class. In other words, an abstract class is one that cannot be instantiated and can only be used as a parent class in other derived (concrete) classes. Since this class cannot be instantiated and you cannot use a non-static class without instantiating it, you cannot use the abstract class by itself. You must inherit from it in other class(es) to use it.

An abstract class may have one or more methods that are completely implemented but it must have at least one abstract method that must be implemented in the derived class(es). This is what makes the abstract class - abstract.

So, in a nutshell an abstract class is just like any other class except that it cannot be instantiated and must have one or more abstract (unimplemented) methods.

Interface
An Interface is not a class. It is a contract and all classes that implement the interface must implement all the properties/methods declared in an Interface.

Unlike an abstract class, an interface cannot have actual implementation of any property/method and also all the properties / methods must be declared public.

Since an interface cannot have any implementation, all the classes inheriting this interface must implement all the methods defined in the interface. Abstract class on the other hand can have fully implemented methods and derived classes can simply use that implementation.

If an abstract class has all the methods defined as abstracts, then both Interface and Abstract class is the same.

Why would you use one over the other?

Both interfaces and abstract classes are good if you want to keep the same structure in your classes inheriting from it. But abstract class allows you to implement one or more common method that can be used as is by all the classes. One advantage that interface have over abstract class is that at least in C# and VB.NET (also true in Java but not in C++) a class can only inherit from one class, while it can implement multiple interfaces.

Interfaces are generally used to define the abilities of a class i.e. what a class can do. For example - IComparable interface. This interface defines "Compare To" signature which can be implemented in the class to compare the instance of an object with another object of the same type. Any class that implements IComparable interface must be capable of doing so.

Abstract classes on the other hand generally implement or define the core capability of the class. For example a MemoryStream class can inherit from a Stream abstract class that implements a Serialize method to serialize the content.

You generally want to use interface if various classes only share certain features, although they may be of different type. For example, a class called Car and a class called Plane may implement the same IMovable interface. You want to use an abstract class when both classes are of same or similar kind. For example a class "BMW" and a class "Lexus" can inherit from the same abstract class called "Car".

If you modify an interface and add a new method, you must modify all the classes implementing that interface to implement that method. You can however modify an abstract class and as long as you fully implement a new method, you don't have to touch other classes inheriting from it.

Let's see both Interface and Abstract class in action.

Abstract Class

Using System;
namespace AbstractInterface
{
    public abstract class Student  
           // notice keyword abstract. In VB.NET the equivalent keyword is MustInherit
     { 
        protected string studentnum;     //protected variables
        protected string studentname;


      public abstract String StudentNumber 
              // notice the keyword abstract. The property is not fully implemented.
           {
             get;
             set;
           }
      public abstract String StudentName
        {
           get;
           set;
        }
     public String GetStudentInfo() // notice this method is fully implemented
      {
        return "Student Number: " + studentnum + " Name: " + studentname;
      }
     public abstract String EnrollmentStatus(); // notice this method is not implemented.


    }
}
   
Concrete Class


using system;
namespace AbstractInterface
{
    public class GraduateStudent : Student // this class inherits from Student class.
   {
     public GraduateStudent()   //constructor
      {
       }
      public override String StudentNumber
           // remember abstract class didn't implement this property so we have to implement it here.
           //   Notice keyword override
        {
           get
            {
               return studentnum;
            }
            set
            {
               studentnum = value;
            }
        }
        public override String StudentName
         
        {
           get
            {
               return studentname;
            }
            set
            {
               studentname = value;
            }
        }


      public new String GetStudentInfo() // this method is implemented in base class.
      {
        return base.GetStudentInfo();
      }


    }
    public override String  EnrollmentStatus () // notice this method is not implemented in base class


      {
        return studentname + " is enrolled."
      }


    }
}

Now lets see an Interface Example

Interface


Public interface IStudent // As a convention, interfaces are prefixed with "I"
{


 String StudentNumber
              // No need to specific "public" since interface can only have public properties/methods.
           {
             get;
             set;
           }
      String StudentName
        {
           get;
           set;
        }
     String GetStudentInfo();
     
     String EnrollmentStatus();
   
          // notice no implementation of any method or property
   }

Concrete Class using Interface


using system;
namespace AbstractInterface
{
     public class Student2 : IStudent    // implements interface


      protected string studentnum;     //protected variables
      protected string studentname;


     public  Student2  ()   //constructor
        {
        }
      public String StudentNumber
           // must be implemented here, otherwise compiler will throw error.
         
        {
           get
            {
               return studentnum;
            }
            set
            {
               studentnum = value;
            }
        }
        public String StudentName
       
        {
           get
            {
               return studentname;
            }
            set
            {
               studentname = value;
            }
        }


      public String GetStudentInfo() // implemented here
      {
        return "Student Number: " + studentnum + " Name: " + studentname;
      }


    }
    public String  EnrollmentStatus ()


      {
        return studentname + " is enrolled."
      }


   // notice - all properties and methods declared in interface must be implemented. Every class inheriting       //from this interface must implement all of them.


    }


}

Hopefully this will help clarify some of the differences between an Interface and an Abstract class. As always, your comments are welcome.

Wednesday, February 8, 2012

Classes and Objects in Object Oriented Programming

All Programming Fundamentals! In my previous post, I wrote about four principles of Object Oriented Programming. Today, we will take it one step further and discuss the concept of a Class and an Object. We will also discuss types of classes.

Class is a template that exhibit certain characteristics. For example, blueprint of a house defines the number of rooms, doors, room size etc. You can use this blueprint to build one or more houses. Similarly, class is a blueprint that can be used to build objects. Each class must have a name, one or more attributes or properties, one or more methods that can be used to perform operations on the object(s) created from this class. For example, A class called "Student" may have the following format.

Class Name
Properties
Methods

An object is an instance of the class. In your application, you can declare an instance of the class and assign it to a variable which will then allow you to access the public properties to read or set the values and use the public methods to perform operations. 

We will talk more about the Public vs. Private vs. Protected Properties/Methods in future post, but for now just remember that any object can access public methods and properties of another object (there are some caveats to it, such as they must be in the same assembly or the consuming object's assembly must reference the assembly where the object resides and they must be imported in the class either by Imports or Using statement on top of the class - more on that later).

Some classes don't need to be instantiated before they can be used. Their public methods and properties are always available without having to instantiate and create an object. I guess you could say that your application automatically creates an instance of the class for all other classes to use.

Remember, while you can have many instances of the class that can be instantiated and one instance will not share the other instance. For example, you can have two instances (objects) of "Student" class called "Student 1" and "Student 2". The properties of "Student 1" will be different than that of "Student 2". Classes that can't be instantiated by definition only have one instance hence only one set of properties.

In C#,  a class declared with STATIC keyword cannot be instantiated. In VB.NET, you don't have a shared class per se, but a Module is closest to the static class. 

In a static class, all methods must be declared static. However a non-static class can have both static and non-static members. Static members will be available regardless of whether the class is instantiated and only one copy of static member will exist, while there can be multiple instances of non-static members. In VB.NET, you can declare methods with keyword SHARED  which will have the same behavior as STATIC in C#.

Constructors
Constructors allows non-static classes to be instantiated. In VB.NET, the constructor is declared as a Public Sub New. In C#, the constructor is same name as the class name. You can have more than one constructor per class. (See example below)


Example:

C#
using System;
namespace 6thGrade
{
public class Student
{
   private int _age;
   private string _name;

   // Default constructor:
   public Student() 
   {
      _name = "N/A";    // assigning a value "N/A" to private string variable name.
   }

   // Another Constructor:
   public Student(string name, int age) 
   {
      this._name = name; // assigning a value passed to the constructor to variable name.
      this._age = age;  // assigning a value passed to the constructor to variable age.
   }

   // Printing method:
   public void PrintStudent() 
   {
      Console.WriteLine("{0}, {1} years old.", name, age);
   }
}
}

VB.NET

Imports System
Namespace 6thGrade
Public Class Student

     Private _age As Int32
     Private _name As String

    Public Sub New()     // default constructor
          name="N/A"
    End Sub
    
    Public Sub New(ByVal name As String, ByVal age As Int32)
          _name=name
          _age=age
    End Sub
    
    Public Sub PrintStudent()
       Console.Writeline(name + ", " + age)
    End Sub
End Class
End Namespace

STATIC CLASS 

C#
using System;
namespace 6thGrade
{
public static class Student
{
   private int _age;
   private string _name;

  //static method
public static void studentinfo(string name, int age)
{
_name=name;
_age = age;
}

   // Printing method:
   public static void PrintStudent() 
   {
      Console.WriteLine("{0}, {1} years old.", name, age);
   }
}
}

VB.NET

Imports System
Namespace 6thGrade
Public Class Student                          // No Static equivalent in VB.NET

     Private _age As Int32
     Private _name As String

    Public Sub New()     // default constructor
          name="N/A"
    End Sub
    
Public Shared Sub studentinfo(ByVal name As String, ByVal age As Int32)
{
_name=name
_age = age
}
Public Shared Sub PrintStudent()
       Console.Writeline(name + ", " + age)
    End Sub
End Class
End Namespace

We will talk more about classes and associations, compositions, property/method accessibility etc in subsequent posts.

Thank you and as always, your comments are welcome!