Showing posts with label Constructors and destructors. Show all posts
Showing posts with label Constructors and destructors. Show all posts

Sunday, March 30, 2014

Classes in C#

Classes

A class is a construct that enables you to create your own custom types by grouping together variables of other types, methods and events. Classes are declared by using the keyword class followed by the class name and a set of class members surrounded by curly braces.
If the class is not declared as static, client code can use it by creating objects or instances which are assigned to a variable. The variable remains in memory until all references to it go out of scope. At that time, the CLR marks it as eligible for garbage collection. If the class is declared as static, then only one copy exists in memory and client code can only access it through the class itself, not an instance variable.

Structs

Structs are defined by using the struct keyword, for example:
public struct PostalAddress
{
    // Fields, properties, methods and events go here...
}
Structs share most of the same syntax as classes, although structs are more limited than classes:
·         Within a struct declaration, fields cannot be initialized unless they are declared as const or static.
·         A struct cannot declare a default constructor (a constructor without parameters) or a destructor.
·         Structs are copied on assignment. When a struct is assigned to a new variable, all the data is copied, and any modification to the new copy does not change the data for the original copy. This is important to remember when working with collections of value types such as Dictionary.
·         Structs are value types and classes are reference types.
·         Structs can declare constructors that have parameters.
·         A struct cannot inherit from another struct or class, and it cannot be the base of a class. All structs inherit directly from System.ValueType, which inherits from System.Object.
·         A struct can implement interfaces.
·         A struct can be used as a nullable type and can be assigned a null value.
Abstract Classes:
Classes can be declared as abstract by putting the keyword abstract before the class definition. For example:
public abstract class A
{
    // Class members here.
}
An abstract class cannot be instantiated. The purpose of an abstract class is to provide a common definition of a base class that multiple derived classes can share. An abstract class may be fully implemented, but is more usually partially implemented or not implemented at all, thereby encapsulating common functionality for inherited classes
Abstract classes may also define abstract methods. This is accomplished by adding the keyword abstract before the return type of the method. For example:
public abstract class A
{
    public abstract void DoWork(int i);
}
Abstract methods have no implementation, so the method definition is followed by a semicolon instead of a normal method block. Derived classes of the abstract class must implement all abstract methods. When an abstract class inherits a virtual method from a base class, the abstract class can override the virtual method with an abstract method. For example:
// compile with: /target:library 
public class D
{
    public virtual void DoWork(int i)
    {
        // Original implementation.
    }
}
 
public abstract class E : D
{
    public abstract override void DoWork(int i);
}
 
public class F : E
{
    public override void DoWork(int i)
    {
        // New implementation.
    }
}
If a virtual method is declared abstract, it is still virtual to any class inheriting from the abstract class. A class inheriting an abstract method cannot access the original implementation of the method—in the previous example, DoWork on class F cannot call DoWork on class D. In this way, an abstract class can force derived classes to provide new method implementations for virtual methods.
An abstract property declaration does not provide an implementation of the property accessors - it declares that the class supports properties, but leaves the accessor implementation to derived classes. The following example demonstrates how to implement the abstract properties inherited from a base class.
// compile with: csc /target:library abstractshape.cs 
public abstract class Shape
{
    private string name;
 
    public Shape(string s)
    {
        // calling the set accessor of the Id property.
        Id = s;
    }
 
    public string Id
    {
        get
        {
            return name;
        }
 
        set
        {
            name = value;
        }
    }
 
    // Area is a read-only property - only a get accessor is needed: 
    public abstract double Area
    {
        get;
    }
 
    public override string ToString()
    {
        return Id + " Area = " + string.Format("{0:F2}", Area);
    }
}
Modifiers on the property are placed on the property declaration itself. For example: “public abstract double Area”.
 
When declaring an abstract property (such as Area in this example), you simply indicate what property accessors are available, but do not implement them. In this example, only a get accessor is available, so the property is read-only.
// compile with: csc /target:library /reference:abstractshape.dll shapes.cs 
public class Square : Shape
{
    private int side;
 
    public Square(int side, string id)
        : base(id)
    {
        this.side = side;
    }
 
    public override double Area
    {
        get
        {
            // Given the side, return the area of a square: 
            return side * side;
        }
    }
}
 
public class Circle : Shape
{
    private int radius;
 
    public Circle(int radius, string id)
        : base(id)
    {
        this.radius = radius;
    }
 
    public override double Area
    {
        get
        {
            // Given the radius, return the area of a circle: 
            return radius * radius * System.Math.PI;
        }
    }
}
 
public class Rectangle : Shape
{
    private int width;
    private int height;
 
    public Rectangle(int width, int height, string id)
        : base(id)
    {
        this.width = width;
        this.height = height;
    }
 
    public override double Area
    {
        get
        {
            // Given the width and height, return the area of a rectangle: 
            return width * height;
        }
    }
}
 
 
Interfaces:
An interface contains only the signatures of methods, properties, events or indexers. A class or struct that implements the interface must implement the members of the interface that are specified in the interface definition. In the following example, class ImplementationClass must implement a method named SampleMethod that has no parameters and returns void.
interface ISampleInterface
{
    void SampleMethod();
}
 
class ImplementationClass : ISampleInterface
{
    // Explicit interface member implementation:  
    void ISampleInterface.SampleMethod()
    {
        // Method implementation.
    }
}
1.      An interface can be a member of a namespace or a class and can contain signatures of the following members:
·         Methods
·         Properties
·         Indexers
·         Events
2.      An interface can inherit from one or more base interfaces.
3.      When a base type list contains a base class and interfaces, the base class must come first in the list.
4.      A class that implements an interface can explicitly implement members of that interface. An explicitly implemented member cannot be accessed through a class instance, but only through an instance of the interface.
If a class implements two interfaces that contain a member with the same signature, then implementing that member on the class will cause both interfaces to use that member as their implementation. In the following example, all the calls to Paint invoke the same method.
class Test 
{
    static void Main()
    {
        SampleClass sc = new SampleClass();
        IControl ctrl = (IControl)sc;
        ISurface srfc = (ISurface)sc;
 
        // The following lines all call the same method.
        sc.Paint();
        ctrl.Paint();
        srfc.Paint();
    }
}
 
 
interface IControl
{
    void Paint();
}
interface ISurface
{
    void Paint();
}
class SampleClass : IControl, ISurface
{
    // Both ISurface.Paint and IControl.Paint call this method.  
    public void Paint()
    {
        Console.WriteLine("Paint method in SampleClass");
    }
}
 
// Output: 
// Paint method in SampleClass 
// Paint method in SampleClass 
// Paint method in SampleClass
If the two interface members do not perform the same function, however, this can lead to an incorrect implementation of one or both of the interfaces. It is possible to implement an interface member explicitly—creating a class member that is only called through the interface, and is specific to that interface. This is accomplished by naming the class member with the name of the interface and a period. For example:
public class SampleClass : IControl, ISurface
{
    void IControl.Paint()
    {
        System.Console.WriteLine("IControl.Paint");
    }
    void ISurface.Paint()
    {
        System.Console.WriteLine("ISurface.Paint");
    }
}
The class member IControl.Paint is only available through the IControl interface, and ISurface.Paint is only available through ISurface. Both method implementations are separate, and neither is available directly on the class
5.      An interface can't contain constants, fields, operators, instance constructors, destructors, or types. Interface members are automatically public, and they can't include any access modifiers. Members also can't be static.
6.      To implement an interface member, the corresponding member of the implementing class must be public, non-static, and have the same name and signature as the interface member.
Difference between Interface & Abstract Class:
Feature Interface Abstract class
Multiple inheritance A class may inherit several interfaces. A class may inherit only one abstract class.
Default implementation An interface cannot provide any code, just the signature. An abstract class can provide complete, default code and/or just the details that have to be overridden.
Access Modfiers
An interface cannot have access modifiers for the subs, functions, properties etc everything is assumed as public
An abstract class can contain access modifiers for the subs, functions, properties
Core VS Peripheral Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface. An abstract class defines the core identity of a class and there it is used for objects of the same type.
Homogeneity If various implementations only share method signatures then it is better to use Interfaces. If various implementations are of the same kind and use common behaviour or status then abstract class is better to use.
Speed Requires more time to find the actual method in the corresponding classes. Fast
Adding functionality (Versioning) If we add a new method to an Interface then we have to track down all the implementations of the interface and define implementation for the new method. If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.
Fields and Constants
No fields can be defined in interfaces
An abstract class can have fields and constrants defined
 
Sealed Classes:
Classes can be declared as sealed by putting the keyword sealed before the class definition. For example:
public sealed class D
{
    // Class members here.
}
A sealed class cannot be used as a base class. For this reason, it cannot also be an abstract class.
A method, indexer, property, or event, on a derived class that is overriding a virtual member of the base class can declare that member as sealed. This negates the virtual aspect of the member for any further derived class. For example:
public class D : C
{
    public sealed override void DoWork() { }
}

Static Classes:

A static class is basically the same as a non-static class, but there is one difference: a static class cannot be instantiated. In other words, you cannot use the new keyword to create a variable of the class type. Because there is no instance variable, you access the members of a static class by using the class name itself
The following list provides the main features of a static class:
·         Contains only static members.
·         Cannot be instantiated.
·         Is sealed and therefore cannot be inherited
·         They cannot inherit from any class except Object
·         Cannot contain Instance Constructors.
Static Members:
1.      A non-static class can contain static methods, fields, properties, or events.
2.      The static member is callable on a class even when no instance of the class has been created.
3.      The static member is always accessed by the class name, not the instance name. Only one copy of a static member exists, regardless of how many instances of the class are created.
4.      Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
Members of a class are:
  • Constructors
  • Destructors
  • Fields
  • Methods
  • Properties
  • Indexers
  • Delegates
  • Events
  • Nested Classes


Access Identifiers: All types and type members have an accessibility level, which controls whether they can be used from other code in your assembly or other assemblies. You can use the following access modifiers to specify the accessibility of a type or member when you declare it:

public :The type or member can be accessed by any other code in the same assembly or another assembly that references it.

private : The type or member can be accessed only by code in the same class or struct.

protected :The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.

internal :The type or member can be accessed by any code in the same assembly, but not from another assembly.

protected internal :The type or member can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly. Access from another assembly must take place within a class declaration that derives from the class in which the protected internal element is declared, and it must take place through an instance of the derived class type.
 
Constructor: Every class has a constructor, which is called automatically any time an instance of a class is created. The purpose of constructors is to initialize class members when an instance of the class is created. Constructors do not have return values and always have the same name as the class. Listing 7-1 is an example of a class.
Listing 7-1. Example C# Classes:
// Namespace Declaration
using System;

// helper class
class OutputClass
{
    string myString;

    // Constructor
    public OutputClass(string inputString)
    {
        myString = inputString;
    }

    // Instance Method
    public void printString()
    {
        Console.WriteLine("{0}", myString);
    }

    // Destructor
    ~OutputClass()
    {
        // Some resource cleanup routines
    }
}

// Program start class
class ExampleClass
{
    // Main begins program execution.
    public static void Main()
    {
        // Instance of OutputClass
        OutputClass outCl = new OutputClass("This is printed by the output class.");

        // Call Output class' method
        outCl.printString();
    }
}


Constructors are not mandatory, as indicated by the implementation of ExampleClass. In this case, a default constructor is provided. A default constructor is simply a constructor with no arguments.


Default Constructors

If a class does not have a constructor, a default constructor is automatically generated and default values are used to initialize the object fields. A default constructor is simply a constructor with no arguments.

Instance/Parameterized Constructors

Instance constructors are used to create and initialize any instance member variables when you use the new expression to create an object of a class. To initialize a static class, or static variables in a non-static class, you must define a static constructor. The following example shows an instance constructor:
class CoOrds
{
    public int x, y;
 
    // constructor 
    public CoOrds()
    {
        x = 0;
        y = 0;
    }
}

Private Constructors

A private constructor is a special instance constructor. It is generally used in classes that contain static members only. If a class has one or more private constructors and no public constructors, other classes (except nested classes) cannot create instances of this class. For example:
class NLog
{
    // Private Constructor: 
    private NLog() { }
 
    public static double e = Math.E;  //2.71828...
}
The declaration of the empty constructor prevents the automatic generation of a default constructor. Note that if you do not use an access modifier with the constructor it will still be private by default. However, the private modifier is usually used explicitly to make it clear that the class cannot be instantiated.

Static Constructors

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced.
class SimpleClass
{
    // Static variable that must be initialized at run time. 
    static readonly long baseline;
 
    // Static constructor is called at most one time, before any 
    // instance constructor is invoked or member is accessed. 
    static SimpleClass()
    {
        baseline = DateTime.Now.Ticks;
    }
}
Static constructors have the following properties:
·         A static constructor does not take access modifiers or have parameters.
·         A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.
·         A static constructor cannot be called directly.
·         The user has no control on when the static constructor is executed in the program.
·         A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.
·         Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.
·         If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.

Copy Constructor

C# doesn't provide a copy constructor for objects, but you can write one yourself.
Some important information about constructors:
1.       In the inheritance hierarchy, always the base class constructor is called first. In c#, the base keyword is used to access the base class constructor as shown below.
In the below code we declare a constructor in a derived class. We have used the ':base(...)' keyword after the constructor declaration with a specific parameter list.
classAccount
{
        private string mCode;
        private string mName;
        private string mDescription;
        private double mBalance;
 
        public Account(string code, string name, string description, double balance)
        {
            mCode = code;
            mName = name;
            mDescription = description;
            mBalance = balance;
        }
        public Account()
        {
 
        }
}
 
class PartyAccount :Account
 {
            private string mAddress;
            private string mPhone;
            public PartyAccount(string code, string name, string description, double balance, string address, string phone) : base(code, name, description, balance)
    {
        mAddress = address;
        mPhone = phone;
    }
 
    public PartyAccount() : base()
    {
 
    }
}



Destructors

Destructors are used to destruct instances of classes.
1.       Destructors cannot be defined in structs. They are only used with classes.
2.       A class can only have one destructor.
3.       Destructors cannot be inherited or overloaded.
4.       Destructors cannot be called. They are invoked automatically.
5.       A destructor does not take modifiers or have parameters.
6.       Destructor call from the most-derived to the least-derived.
For example, the following is a declaration of a destructor for the class Car:
class Car
{
    ~Car()  // destructor
    {
        // cleanup statements...
    }
}
The destructor implicitly calls Finalize on the base class of the object. Therefore, the previous destructor code is implicitly translated to the following code:
protected override void Finalize()
{
    try
    {
        // Cleanup statements...
    }
    finally
    {
        base.Finalize();
    }
}

Properties

A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they are public data members, but they are actually special methods called accessors. This enables data to be accessed easily and still helps promote the safety and flexibility of methods.
public class Date
{
    private int month = 7;  // Backing store 
 
    public int Month
    {
        get
        {
            return month;
        }
        set
        {
            if ((value > 0) && (value < 13))
            {
                month = value;
            }
        }
    }
}

·         A get property accessor is used to return the property value, and a set accessor is used to assign a new value. These accessors can have different access levels.
·         The value keyword is used to define the value being assigned by the set accessor.
·         Properties that do not implement a set accessor are read only.
·         For simple properties that require no custom accessor code, consider the option of using auto-implemented properties. 
Properties can be declared on an interface. The following is an example of an interface indexer accessor:
public interface ISampleInterface
{
    // Property declaration: 
    string Name
    {
        get;
        set;
    }
}
The accessor of an interface property does not have a body. Thus, the purpose of the accessors is to indicate whether the property is read-write, read-only, or write-only.



Indexers

Indexers allow instances of a class or struct to be indexed just like arrays. Indexers resemble properties except that their accessors take parameters.
In the following example, a generic class is defined and provided with simple get and set accessor methods as a means of assigning and retrieving values. The Program class creates an instance of this class for storing strings

class SampleCollection

{

    // Declare an array to store the data elements. 
    private T[] arr = new T[100];
 
    // Define the indexer, which will allow client code 
    // to use [] notation on the class instance itself. 
    // (See line 2 of code in Main below.)         
    public T this[int i]
    {
        get
        {
            // This indexer is very simple, and just returns or sets 
            // the corresponding element from the internal array. 
            return arr[i];
        }
        set
        {
            arr[i] = value;
        }
    }
}
 
// This class shows how client code uses the indexer. 
class Program
{
    static void Main(string[] args)
    {
        // Declare an instance of the SampleCollection type.
        SampleCollection<string> stringCollection = new SampleCollection<string>();
 
        // Use [] notation on the type.
        stringCollection[0] = "Hello, World";
        System.Console.WriteLine(stringCollection[0]);
    }
}
// Output: 
// Hello, World.
1.       Indexers enable objects to be indexed in a similar manner to arrays.
2.       A get accessor returns a value. A set accessor assigns a value.
3.       The this keyword is used to define the indexers.
4.       The value keyword is used to define the value being assigned by the set indexer.
5.       Indexers do not have to be indexed by an integer value; it is up to you how to define the specific look-up mechanism.
6.       Indexers can be overloaded.
7.       Indexers can have more than one formal parameter, for example, when accessing a two-dimensional array.
8.       Indexers can be used in interfaces