Thursday, September 10, 2009

Permitted and Not permitted class combinations

public class ZClass<T>

{

}

public class XClass<T> : ZClass<T>

{

}

public class BClass<Y>

{

}

public class AClass<Z> : BClass<int>

{

}

public class YClass : ZClass<int>

{

}

/*

public class AClass<Z> : BClass<Y>

{

[ illegal ]

}

public class YClass: ZClass<T>

{

[ illegal ]

}

*/

Ref:
http://shiman.wordpress.com/2008/07/15/c-net-generics-inheritance/

Sealed Class

A sealed class is a class that does not allow inheritance. Some object model designs need to allow the creation of new instances but not inheritance, if this is the case, the class should be declared as sealed.
Specifies that a class cannot be inherited (used as a base class). Note that .NET does not permit a class to be both abstract and sealed.
To create a sealed class in C#, the class declaration should be done as:sealed class Shape

sealed class SealedClass

{
//To create a sealed class in VB.NET, the class declaration should be done as: NonInheritable Class Shape
public void fun()
{
Console.WriteLine("SealedClass");
}
}

static void Main (string[] args)
{
SealedClass objSealedClass = new SealedClass();
objSealedClass.fun();
}

Abstract Class

Abstraction is "the process of identifying common patterns that have systematic variations; an abstraction represents the common pattern and provides a means for specifying which variation to use" (Richard Gabriel).
An abstract class is a parent class that allows inheritance but can never be instantiated. Abstract classes contain one or more abstract methods that do not have implementation. Abstract classes allow specialization of inherited classes.

Indicates that a class is to be used only as a base class for other classes. This means that you cannot create an instance of the class directly. Any class derived from it must implement all of its abstract methods and accessors. Despite its name, an abstract class can possess non-abstract methods and properties.


public
abstract class Shape

{
private float _area;
private System.Drawing.Color _color;
private float _perimeter;
public float Area
{
get
{
return _area;
}
set
{
_area = value;
}
}
public System.Drawing.Color Color
{
get
{
return _color;
}
set
{
_color = value;
}
}
public float Perimeter
{
get
{
return _perimeter;
}
set
{
_perimeter = value;
}
}
public abstract void CalculateArea();
public abstract void CalculatePerimeter();
}

class Rectangle : Shape
{
private float _height;
private float _width;
public Rectangle(float height, float width)
{
_height = height;
_width = width;
}
public float Height
{
get
{
return _height;
}
set
{
_height = value;
}
}
public float Width
{
get
{
return _width;
}
set
{
_width = value;
}
}
public override void CalculateArea()
{
this.Area = _height * _width;
}
public override void CalculatePerimeter()
{
this.Perimeter = (_height * 2) + (_width * 2);
}
public void Display()
{
Console.WriteLine("Perimeter{0}", this.Perimeter);
Console.WriteLine("Area{0}", this.Area);
}
}

static void Main (string[] args)
{
Rectangle objRectangle = new Rectangle(10, 20);
objRectangle.CalculateArea();
objRectangle.CalculatePerimeter();
objRectangle.Display();
}

Wednesday, September 9, 2009

Inheritance (virtual, abstract, override)

public abstract class Account

{

private string name; // Only accessible in base class

protected double balance;// Accessible in base class and derived Class

//constructor to initialize these fields

public Account(string nm, double bal)

{

this.name = nm;

this.balance = bal;

}

//The virtual keyword means these methods can be overridden in derived classes:

public virtual void Credit(double amount)

{

this.balance += amount;

}

public virtual void Debit(double amount)

{

this.balance -= amount;

}

public virtual void Display()

{

Console.WriteLine("Name={0}, balance={1}", this.name,this.balance);

}

//this method is not marked as virtual, it cannot be overridden in derived classes.

//This method provides the capability to change the name of the account holder.

public void ChangeName(string newName)

{

this.name = newName;

}

//The abstract keyword means this method must be overridden in derived classes:

public abstract double CalculateBankCharge();

}

public class SavingsAccount : Account

{

private double minBalance;// If the balance drops below minBalance, the bank will charge a fee on the account

//Modify the SavingsAccount constructor to initialize the fields in the base class and in this class:

public SavingsAccount(string nm, double bal, double min)

: base(nm, bal)// Call base-class constructor first

{

minBalance = min; // Then initialize fields in this class

}

//These methods override the virtual methods inherited from the base class:

public override void Debit(double amount)

{

if (amount <= balance) // Use balance, inherited from base class

base.Debit(amount); // Call Debit, inherited from base class

}

public override void Display()

{

base.Display();// Call Display, inherited from base class

Console.WriteLine("$5 charge if balance goes below ${0}", minBalance);

}

//You must override all abstract methods from the base class

public override double CalculateBankCharge()

{

if (balance < minBalance)

return 5.00;

else

return 0.00;

}

}

static void Main (string[] args)

{

//Account aca = new Account("sd", 1.1);//Cannot create an instance of the abstract class or interface

SavingsAccount sa = new SavingsAccount("Senthil", 100.00, 25);

sa.Display();

//call public methods in SavingsAccount or Account

sa.Credit(100);

sa.Debit(180);

sa.ChangeName("Kumar");

sa.Display();

Console.WriteLine("Bank charge: ${0}", sa.CalculateBankCharge());

}

Ref: http://support.microsoft.com/kb/307205









Interface Example-2

interface INode
{
string Text{get;set;}
object Tag{get;set;}

int Height{get;set;}

int Width{get;set;}

float CalculateArea();
}
public class Node : INode
{
public Node(){}
#region INode Members
public string Text
{
get
{
return m_text;
}
set
{
m_text = value;
}
}
private string m_text;
public object Tag
{
get
{
return m_tag;
}
set
{
m_tag = value;
}
}
private object m_tag = null;
public int Height
{
get
{
return m_height;
}
set
{
m_height = value;
}
}
private int m_height = 0;
public int Width
{
get
{
return m_width;
}
set
{
m_width = value;
}
}
private int m_width = 0;
public float CalculateArea()
{
if ((m_width < 0) (m_height < 0))
return 0;
return m_height * m_width;
}
#endregion
}
class ClonableNode : INode, ICloneable
{
public object Clone()
{
return null;
}
#region INode Members
public string Text
{
get
{
return m_text;
}
set
{
m_text = value;
}
}
private string m_text;
public object Tag
{
get
{
return m_tag;
}
set
{
m_tag = value;
}
}
private object m_tag = null;
public int Height
{
get
{
return m_height;
}
set
{
m_height = value;
}
}
private int m_height = 0;
public int Width
{
get
{
return m_width;
}
set
{
m_width = value;
}
}
private int m_width = 0;
public float CalculateArea()
{
if ((m_width < 0) (m_height < 0))
return 0;
return m_height * m_width;
}
#endregion
}
/// <summary>
/// Summary description for TestClass.
/// </summary>
//class TestClass
//{
// /// <summary>
// /// The main entry point for the application.
// /// </summary>
// [STAThread]
// static void Main (string[] args)
// {
// INode node;
// node = new Node();
// node.Height = 10;
// node.Width = 20;
// float area = node.CalculateArea();
// Console.WriteLine(area);
// Console.WriteLine();
// // multiple inherirance
// ClonableNode nodeC = new ClonableNode();
// object obj = nodeC.Clone();
// nodeC.Height = 200;
// area = nodeC.CalculateArea();
// Console.WriteLine(area);
// if(nodeC is INode)
// Console.WriteLine("nodeC is object of INode type");
// else Console.WriteLine("nodeC isn't object of INode type");
// }
//}
static void Main (string[] args)
{
INode node;
node = new Node();
node.Height = 10;
node.Width = 20;
float area = node.CalculateArea();
Console.WriteLine(area);
Console.WriteLine();
Console.WriteLine("Interfaces (multiple inherirance)");
ClonableNode nodeC = new ClonableNode();
object obj = nodeC.Clone();
nodeC.Height = 200;
area = nodeC.CalculateArea();
Console.WriteLine(area);
if (nodeC is INode)
Console.WriteLine("nodeC is object of INode type");
else Console.WriteLine("nodeC isn't object of INode type");
}

____________________________________
Example
2 interface with same method name, how to implement in derived class
interface IA

    {

        void Display();
    }

interface IB
    {
        void Display();
    }

class CA
    {
        public void Display()
        {
            Console.WriteLine("I am from CA");
        }
    }

 class CB : CA, IA, IB
    {}   

class BB : CA, IA, IB
  {
  void IA.Display() { Console.WriteLine("I am from IA.Display"); }
  void IB.Display() { Console.WriteLine("I am from IB.Display"); }
  //public new void Display() { Console.WriteLine("I am from BB.Display"); }
 }

static void Main(string[] args)
        {
   
         
       
     CB cb = new CB();
     cb.Display(); // displays class CA Display method.

     BB bb = new BB();
     bb.Display(); // displays class CA Display method.
     (bb as IA).Display(); // displays IA.Display
     (bb as IB).Display(); // displays class A Display method.
 }

 Output
I am from CA
I am from CA
I am from IA.Display
I am from IB.Display

____________________________________
Example
 

   interface IParentInterface

    {

        void ParentInterfaceMethod();
    }

    interface IMyInterface : IParentInterface
    {
        void MethodToImplement();
    }

    class InterfaceImplementer : IMyInterface
    {
        public void MethodToImplement()
        {
            Console.WriteLine("MethodToImplement() called.");
        }

        public void ParentInterfaceMethod()
        {
            Console.WriteLine("ParentInterfaceMethod() called.");
        }
    }
static void Main(string[] args)
        {  
InterfaceImplementer iImp = new InterfaceImplementer();
            iImp.MethodToImplement();
            iImp.ParentInterfaceMethod(); 
}

 
Output

MethodToImplement() called.
ParentInterfaceMethod() called.