Static Classes
A class can be declared static, which indicates
that it contains only static members. It is not possible to use the new keyword
to create instances of a static class. Static classes are loaded automatically
by the .NET Framework common language runtime (CLR) when the program or
namespace that contains the class is loaded.
Use
a static class to contain methods that are not associated with a particular
object. For example, it is a common requirement to create a set of methods that
do not act on instance data and are not associated to a specific object in your
code. You could use a static class to hold those methods.
Following
are the main features of a static class:
·
They only contain static
members.
·
They cannot be
instantiated.
·
They are sealed.
·
They cannot contain
Instance Constructors (C# Programming Guide).
Creating
a static class is therefore basically the same as creating a class that
contains only static members and a private constructor. A private constructor
prevents the class from being instantiated.
The
advantage of using a static class is that the compiler can check to make sure
that no instance members are accidentally added. The compiler will guarantee
that instances of this class cannot be created.
Static
classes are sealed and therefore cannot be inherited. They cannot inherit from
any class except Object. Static classes cannot contain an instance constructor;
however, they can have a static constructor. For more information
Static Members
A
static method, field, property, or event is callable on a class even when no
instance of the class has been created. If any instances of the class are
created, they cannot be used to access the static member. Only one copy of
static fields and events exists, and static methods and properties can only
access static fields and static events. Static members are often used to
represent data or calculations that do not change in response to object state;
for example, a math library might contain static methods for calculating sine
and cosine.
Static
methods can be overloaded but not overridden.
Static
class members are declared by using the static keyword before the return type of the member, for example:
Public keyword
The public
keyword is an access modifier for types and type members. Public access is the
most permissive access level. There are no restrictions on accessing public
members, as in this example:
class
SampleClass
{
public int x; // No access restrictions.
}
Protected keyword
The protected keyword is a member access modifier. A protected member is
accessible within its class and by derived classes. For a comparison of protected with the other access modifiers, see Accessibility Levels.
A protected member of a base class is accessible
in a derived class only if the access occurs through the derived class type.
For example, consider the following code segment:
class
A
{
protected int x = 123;
}
class
B : A
{
static void Main()
{
A a = new A();
B b = new B();
// Error CS1540, because x can only be
accessed by
// classes derived from A.
// a.x = 10;
// OK, because this class derives from
A.
b.x = 10;
}
}
The
statement a.x
=10 generates an error because A is not derived from B.
Struct members cannot be protected because the
struct cannot be inherited.
Internal keyword
The internal keyword is an access modifier for types and type members.
Internal types or members are accessible only within files in the same
assembly, as in this example:
public
class BaseClass
{
// Only accessible within the same assembly
internal static int x = 0;
}
Private keyword
The private keyword is a member access modifier. Private access is the least
permissive access level. Private members are accessible only within the body of
the class or the struct in which they are declared, as in this example:
class
Employee
{
private int i;
double d;
// private access by default
}
In this
example, the Employee class
contains two private data members, name and salary. As
private members, they cannot be accessed except by member methods. Public
methods named GetName and Salary are
added to allow controlled access to the private members. The name member
is accessed by way of a public method, and the salary member is accessed by way
of a public read-only property
// private_keyword.cs
using System;
class Employee
{
private string name = "FirstName, LastName";
private double salary = 100.0;
public
string GetName()
{
return name;
}
public
double Salary
{
get { return salary; }
}
}
class MainClass
{
static
void Main()
{
Employee e = new Employee();
//
The data members are inaccessible (private), so
//
then can't be accessed like this:
//
string n = e.name;
// double s = e.salary;
//
'name' is indirectly accessed via method:
string n = e.GetName();
//
'salary' is indirectly accessed via property
double s = e.Salary;
}
}
Accessibility Levels
Use the
access modifiers, public, protected, internal, or private, to specify one of
the following declared accessibilities for members.
Declared
accessibility
|
Meaning
|
public
|
Access
is not restricted.
|
protected
|
Access
is limited to the containing class or types derived from the containing
class.
|
internal
|
Access
is limited to the current assembly.
|
protectedinternal
|
Access
is limited to the current assembly or types derived from the containing
class.
|
private
|
Access
is limited to the containing type.
|
Properties
Properties
are members that provide a flexible mechanism to read, write, or compute the
values of private fields. 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.
In this example, the TimePeriod class
stores a time period. Internally the class stores the time in seconds, but a
property named Hours enables
a client to specify a time in hours. The accessors for the Hours property
perform the conversion between hours and seconds.
class TimePeriod
{
private double
seconds;
public double Hours
{
get { return
seconds / 3600; }
set { seconds =
value * 3600; }
}
}
class Program
{
static void Main()
{
TimePeriod t =
new TimePeriod();
// Assigning
the Hours property causes the 'set' accessor to be called.
t.Hours = 24;
// Evaluating
the Hours property causes the 'get' accessor to be called.
System.Console.WriteLine("Time in hours: " + t.Hours);
}
}
Properties Overview
·
Properties enable a class to expose a public way of getting and
setting values, while hiding implementation or verification code.
·
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. For more informationThe value keyword is used to
define the value being assigned by the set indexer.
·
Properties that do not implement a set method are read only.
·
For simple properties that require no custom accessor code,
consider the option of using auto-implemented properties. For more information
Remarks
Properties can be marked as public, private, protected, internal, or protected internal. These access modifiers define how
users of the class can access the property. The get
and set accessors for the same property may have
different access modifiers. For example, the get may
be public to allow read-only access from outside the
type, and the set may be private
or protected. For more informationA property may be
declared as a static property by using the static
keyword. This makes the property available to callers at any time, even if no
instance of the class exists. For more information
A property may be marked as a virtual
property by using the virtual keyword. This enables derived classes to override
the property behavior by using the override keyword. For more information about
these
A property overriding a virtual property
can also be sealed, specifying that for derived classes it is no longer
virtual. Lastly, a property can be declared abstract. This means that there is
no implementation in the class, and derived classes must write their own
implementation.
Enum
The enum keyword is used to declare an enumeration, a distinct type that
consists of a set of named constants called the enumerator list. Every
enumeration type has an underlying type, which can be any integral type except
char. The default underlying type of the enumeration elements is int. By
default, the first enumerator has the value 0, and the value of each successive
enumerator is increased by 1. For example:
enum Days
{Sat, Sun, Mon, Tue, Wed, Thu, Fri};
In this
enumeration, Sat is 0, Sun is 1, Mon is 2, and so
forth. Enumerators can have initializers to override the default values. For
example:
enum Days
{Sat=1, Sun, Mon, Tue, Wed, Thu, Fri};
In this
enumeration, the sequence of elements is forced to start from 1 instead
of 0.
To declare an enum of another integral type,
such as byte, use a colon after the identifier followed by the type:
enum Days
{ Sat, Sun, Mon, Tue, Wed, Thu, Fri };
class Program
{
static void Main(string[]
args)
{
Console.WriteLine(Days.Fri);
Days
d = new Days();
d = Days.Wed;
Console.WriteLine(d);
Console.WriteLine((int)Days.Sat);//Convert enum to int
}
}
this keyword
The this keyword refers to the current instance of the class and is also
used as a modifier of the first parameter of an extension method.
class this_demo
{
int
roll;
string
name;
public
this_demo(int roll, string
name)
{
this.roll
= roll;
this.name
= name;
}
}
Static member functions, because they exist
at the class level and not as part of an object, do not have a this pointer. It is an error to refer to this in a static method.
Indexers
Indexers
are a syntactic convenience that enables you to create a class, struct, or
interface that client applications can access just as an array. Indexers are
most frequently implemented in types whose primary purpose is to encapsulate an
internal collection or array. For example, suppose you have a class named
TempRecord that represents the temperature in Farenheit as recorded at 10
different times during a 24 hour period. The class contains an array named
"temps" of type float to represent the temperatures, and a DateTime
that represents the date the temperatures were recorded. By implementing an
indexer in this class, clients can access the temperatures in a TempRecord
instance as float
temp = tr[4] instead of as float temp = tr.temps[4]. The indexer notation not
only simplifies the syntax for client applications; it also makes the class and
its purpose more intuitive for other developers to understand.
class TempRecord
{
// Array of temperature values
private float[] temps = new float[10] { 56.2F,
56.7F, 56.5F, 56.9F, 58.8F, 61.3F, 65.9F, 62.1F, 59.2F, 57.5F };
}
To declare an indexer on a class or struct, use
the this keyword, as in this example:
class indexer_demo
{
int[]
rate = new int[5];
public int this[int index]
{
set
{
rate[index] = value;
}
get
{
return
rate[index];
}
}
public int Length
{
get
{ return rate.Length; }
}
}
class Program
{
static void Main(string[]
args)
{
indexer_demo
ob = new indexer_demo();
for
(int i = 0; i < ob.Length; i++)
ob[i] = i + 1;
for
(int i = 0; i < ob.Length; i++)
Console.WriteLine(ob[i]);
}
}
Abstract
Classes
The
abstract keyword enables you to create classes and class members solely for the
purpose of inheritance—to define features of derived, non-abstract classes. The
sealed keyword enables you to prevent the inheritance of a class or certain
class members that were previously marked virtual.
Classes
can be declared as abstract. This is accomplished by putting the keyword abstract before the keyword class in the
class definition. For example:
abstract class
Abstract_demo
{
public void show_abstract()
{
Console.WriteLine("This is Abstract Class");
}
}
class Inherit : Abstract_demo
{
public void show_derive()
{
Console.WriteLine("I am drive class function");
}
}
class Program
{
static void Main(string[]
args)
{
Inherit
ob = new Inherit();
ob.show_abstract();
ob.show_derive();
}
}
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. For example, a class library may define an abstract class that is used
as a parameter to many of its functions, and require programmers using that
library to provide their own implementation of the class by creating a derived
class.
Abstract
methods
Abstract
classes may also define abstract methods. This is accomplished by adding the
keyword abstract before
the return type of the method. For example:
abstract class
Abstract_demo
{
public void show_abstract()
{
Console.WriteLine("This is Abstract Class");
}
abstract
public void
abstract_method();
}
class Inherit : Abstract_demo
{
public void show_derive()
{
Console.WriteLine("I am drive class function");
}
public override void
abstract_method()//Implementation
{
Console.WriteLine("I am implementing abstract method");
}
}
class Program
{
static void Main(string[]
args)
{
Inherit
ob = new Inherit();
ob.show_abstract();
ob.show_derive();
ob.abstract_method();
}
}
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 with override keyword putting in abstract function signature in
implementation
Base
keyword
The base keyword is used to access members of the base class from within a
derived class:
·
Call a method on the base class that has been overridden by
another method.
·
Specify which base-class constructor should be called when
creating instances of the derived class.
A base class access is permitted only in a
constructor, an instance method, or an instance property accessor.
It is an error to use the base keyword from within a static method.
// keywords_base.cs
// Accessing base class members
using System;
public class Person
{
protected string ssn = "444-55-6666";
protected string name = "John L. Malgraine";
public
virtual void GetInfo()
{
Console.WriteLine("Name:
{0}", name);
Console.WriteLine("SSN: {0}", ssn);
}
}
class Employee : Person
{
public
string id = "ABC567EFG";
public
override void GetInfo()
{
//
Calling the base class GetInfo method:
base.GetInfo();
Console.WriteLine("Employee ID: {0}", id);
}
}
class TestClass
{
static
void Main()
{
Employee E = new Employee();
E.GetInfo();
}
}
Constructor
Inheritance
This
example shows how to specify the base-class constructor called when creating
instances of a derived class.
public class
BaseClass
{
int
num;
public
BaseClass()
{
Console.WriteLine("in BaseClass()");
}
public
BaseClass(int i)
{
num = i;
Console.WriteLine("in BaseClass(int i)");
}
public int get_num
{
get
{ return num; }
}
}
public class
DerivedClass : BaseClass
{
// This
constructor will call BaseClass.BaseClass()
public
DerivedClass() : base()
{
}
// This
constructor will call BaseClass.BaseClass(int i)
public
DerivedClass(int i) : base(i)
{
}
}
class Program
{
static void Main(string[]
args)
{
DerivedClass
md = new DerivedClass();
DerivedClass
md1 = new DerivedClass(1);
}
}
The virtual keyword is used to modify a method, property, indexer, or event
declaration and allow for it to be overridden in a derived class. For example,
this method can be overridden by any class that inherits it:
The implementation of a virtual member can
be changed by an overriding member in a derived class.
Remarks
When a virtual method is invoked, the run-time
type of the object is checked for an overriding member. The overriding member
in the most derived class is called, which might be the original member, if no
derived class has overridden the member.
By default, methods are non-virtual. You cannot
override a non-virtual method.
You cannot use the virtual modifier with the static, abstract, private, or override modifiers.
Virtual
public class
Dimensions
{
public const double PI = Math.PI;
protected
double x, y;
public
Dimensions()
{
}
public
Dimensions(double x, double
y)
{
this.x
= x;
this.y
= y;
}
public virtual double Area()
{
return
x * y;
}
}
public class Circle : Dimensions
{
public
Circle(double r) : base(r,
0)
{
}
public override double
Area()
{
return
PI * x * x;
}
}
class Sphere : Dimensions
{
public
Sphere(double r): base(r,
0)
{
}
public override double
Area()
{
return
4 * PI * x * x;
}
}
class Cylinder : Dimensions
{
public
Cylinder(double r, double
h) : base(r, h)
{
}
public override double
Area()
{
return
2 * PI * x * x + 2 * PI * x * y;
}
}
class Program
{
static void Main(string[]
args)
{
double
r = 3.0, h = 5.0;
Dimensions
c = new Circle(r);
Dimensions
s = new Sphere(r);
Dimensions
l = new Cylinder(r,
h);
//
Display results:
Console.WriteLine("Area of Circle
= {0:F2}", c.Area());
Console.WriteLine("Area of Sphere
= {0:F2}", s.Area());
Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
}
}
Limiting
Extensibility by Sealing Classes
You can
use sealing to limit the ways in which developers can extend your framework.
When you seal a class, other classes cannot inherit from it. When you seal a
member, derived classes cannot override the implementation of the member. You
should not seal types and members by default. Sealing prevents customization of
library types and members, and impacts the perception of usability for some
developers. In addition, extensibility is one of the fundamental benefits of
using an object-oriented framework. You should carefully weigh decisions that
restrict this benefit.
When
applied to a class, the sealed modifier prevents
other classes from inheriting from it
sealed class
base_class
{
public void show_base()
{
Console.WriteLine("This is sealed class");
}
}
You can also use the sealed
modifier on a method or property that overrides a virtual method or property in
a base class. This enables you to allow classes to derive from your class and
prevent them from overriding specific virtual methods or properties
class test
{
public virtual void overrride_fun()
{
Console.WriteLine("Derive can override me");
}
}
class platform : test
{
sealed public override void overrride_fun()
{
base.overrride_fun();
Console.Write("With base and derive added code");
}
}
class attemt : platform
{
//This
function can not be override because its sealed in parent class
//public
override void overrride_fun()
//{
// Console.WriteLine("New cod efor
override");
//}
}
Delegates
Any
method from any accessible class or struct that matches the delegate's
signature, which consists of the return type and parameters, can be assigned to
the delegate. The method can be either static or an instance method. This makes
it possible to programmatically change method calls, and also plug new code
into existing classes. As long as you know the signature of the delegate, you
can assign your own delegated method.
Any
method from any accessible class or struct that matches the delegate's
signature, which consists of the return type and parameters, can be assigned to
the delegate. The method can be either static or an instance method. This makes
it possible to programmatically change method calls, and also plug new code
into existing classes. As long as you know the signature of the delegate, you
can assign your own delegated method.
Example
A delegate is a type that safely
encapsulates a method, similar to a function pointer in C and C++. Unlike C
function pointers, delegates are object-oriented, type safe, and secure. The
type of a delegate is defined by the name of the delegate
delegate void
mydelegate();
delegate int
mathref(int
a,int b);
namespace ConsoleApplication1
{
class demo
{
int a,
b;
public
demo(int a, int
b)
{
this.a
= a;
this.b
= b;
}
public void add()
{
Console.WriteLine("Result of addition is " + a + b);
}
public int multi(int m, int n)
{
return
m * n;
}
}
class mathdemo
{
public int add(int x, int y)
{
return
x + y;
}
public int sub(int i,int j)
{
return
i-j;
}
}
class Program
{
static void Main(string[]
args)
{
demo
ob = new demo(5,5);
mydelegate
d = ob.add;
mathref
mob = ob.multi;
d();
Console.WriteLine("multi Function of class demo using delegate result
is " + mob(11, 22));
mathdemo
mathob = new mathdemo();
mob = mathob.add;
Console.WriteLine("add Function of class mathdemo using delegate
result is " + mob(10, 20));
mob = mathob.sub;
Console.WriteLine("sub Function of class mathdemo using delegate
result is " + mob(100, 20));
}
}
}
Interface
An interface contains only the signatures
of methods, delegates or events. The implementation of the methods is done in
the class that implements the interface
Remarks
An
interface can be a member of a namespace or a class and can contain signatures
of the following members:
·
Methods
·
Properties
·
Indexers
·
Events
An interface can inherit from one or more base
interfaces.
When a base type list contains a base class and
interfaces, the base class must come first in the list.
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.
interface interface_1
{
void
method1();
}
interface myinterface
{
void
fun1();
}
class implement_interface : myinterface,interface_1 //implement multiple inheritance like
structure
{
public void fun1()
{
Console.WriteLine("I am myinterface function implement by
implement_interface class");
}
public void method1()
{
Console.WriteLine("I am interface_1 function implement by
implement_interface class");
}
}
Interface
Inheritance Interface
An interface can inherit another interface. It
is responsibility of derive class to implement all inherited interface methods
otherwise an error will occurred
interface interface_1
{
void
method1();
}
interface inteface_2
{
void
method2();
}
interface myinterface : interface_1,inteface_2
{
void
fun1();
}
class implement_interface : myinterface
{
public void fun1()
{
Console.WriteLine("I am myinterface function implement by
implement_interface class");
}
public void method1()
{
Console.WriteLine("I am interface_1 function implement by
implement_interface class");
}
public void method2()
{
Console.WriteLine("I am interface_2 function implement by
implement_interface class");
}
}
class Program
{
static void Main(string[]
args)
{
implement_interface
ob = new implement_interface();
ob.fun1();
ob.method1();
ob.method2();
}
}
Explicit Interface Implementation
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
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
interface IControl
{
void Paint();
}
interface ISurface
{
void Paint();
}
public class SampleClass :
IControl, ISurface
{
void IControl.Paint()
{
System.Console.WriteLine("IControl.Paint");
}
void ISurface.Paint()
{
System.Console.WriteLine("ISurface.Paint");
}
}
class Program
{
static void Main(string[]
args)
{
SampleClass
obj = new SampleClass();
//obj.Paint(); // Compiler error.
IControl
c = (IControl)obj;
c.Paint(); // Calls IControl.Paint on SampleClass.
ISurface
s = (ISurface)obj;
s.Paint();
//
Calls ISurface.Paint on SampleClass.
}
}
No comments:
Post a Comment