public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
Coordinate pt1 = new Coordinate();
pt1.latitude = 1.33463167;
pt1.longitude = 103.74697;
}
}
Or you can use the object initializer feature:
private void Form1_Load(object sender, EventArgs e) {
//...
Coordinate pt2 = new Coordinate() {
latitude = 1.33463167,
longitude = 103.74697
};
}
Because structs are value types, assigning one struct to another makes a copy of its value, as the following code sample shows:
private void Form1_Load(object sender, EventArgs e) {
//...
Coordinate pt2 = new Coordinate() {
latitude = 1.33463167,
longitude = 103.74697
};
Coordinate pt3;
pt3 = pt2;
Console.WriteLine("After assigning pt2 to pt3");
Console.WriteLine("pt2: {0}", pt2.ToString());
Console.WriteLine("pt3: {0}", pt3.ToString());
pt3.latitude = 1.45631234;
pt3.longitude = 101.32355;
Console.WriteLine("After changing pt3");
Console.WriteLine("pt2: {0}", pt2.ToString());
Console.WriteLine("pt3: {0}", pt3.ToString());
}
Here's the program's output:
After assigning pt2 to pt3
pt2: 1.33463167,103.74697
pt3: 1.33463167,103.74697
After changing pt3
pt2: 1.33463167,103.74697
pt3: 1.45631234,101.32355
Notice that after changing the properties of pt3
, the latitude and longitude properties of pt2
and pt3
are different.
Memory Allocation
When you use the new keyword to create an instance of a class, the object will be allocated on the heap. When using structs, the struct object is created on the stack instead. Because of this, using structs yields better performance gains. Also, when passing a struct to a method, note that it is passed by value instead of passed by reference.
In general, use classes when dealing with large collections of data. When you have smaller sets of data to deal with, using structs is more efficient.
This chapter explained how to define a class and the various components that make up a class — properties, methods, constructors, and destructors. In addition, it explored the new features in C# 3.0 — object initializers, anonymous types, and automatic properties. While you need to use the new keyword to instantiate a new object, you can also create static classes that can be used without instantiation. Finally, you saw how to use structs, the lightweight alternative to classes, that behave much like classes but are value types.
When defining a class, you have to provide the implementation for all its methods and properties. However, there are times when you do not want to provide the actual implementation of how a class might work. Rather, you want to describe the functionalities of the class. This set of descriptions is like a contract, dictating what the class will do, the types of parameters needed, and the type of return results. In object-oriented programming, this contract is known as an interface.
An interface defines a class and its members without providing any implementation. When using interfaces in programming, generally three parties are involved:
□ Interface definition— The interface defines the composition of a class, such as methods, properties, and so on. However, the interface does not provide any implementation for any of these members.
□ Implementing class— The class that implements a particular interface provides the implementation for all the members defined in that interface.
□ Clients— Objects that instantiate from the implementing classes are known as the client. The client invokes the methods defined in the interface, whose implementation is provided by the implementing class.
Differences between an Interface and an Abstract Base Class
Conceptually, an abstract class is similar to an interface; however, they do have some subtle differences:
□ An abstract class can contain a mixture of concrete methods (implemented) and abstract methods (an abstract class needs at least one abstract method); an interface does not contain any method implementations.
□ An abstract class can contain constructors and destructors; an interface does not.
□ A class can implement multiple interfaces, but it can inherit from only one abstract class.
This chapter explains how to define an interface and how to implement the interface using a class.
Defining an interface is similar to defining a class — you use the interface
keyword followed by an identifier (the name of the interface) and then specify the interface body. For example:
interface IPerson {
string Name { get; set; }
DateTime DateofBirth { get; set; }
ushort Age();
}
Here you define the IPerson
interface containing three members — two properties and one function. You do not use any access modifiers on interface members — they are implicitly public
. That's because the real use of an interface is to define the publicly accessible members (such as methods and properties) of a class so that all implementing classes have the same public members. The implementation of each individual member is left to the implementing class.
The declaration for the Name property consists simply of get
and
set accessors without implementation:
string Name { get; set; }
And the Age()
method simply contains its return type (and input parameters, if any) but without its implementation:
ushort Age();
It's important to note that you cannot create an instance of the interface directly; you can only instantiate a class that implements that interface:
//---error---
IPerson person = new IPerson();
Interface Naming Convention
By convention, begin the name of an interface with a capital I (such as IPerson
, IManager
, IEmployee
, and so on) so that it is clear that you are dealing with an interface.
Implementing an Interface
Once an interface is defined, you can create a new class to implement it. The class that implements that particular interface must provide all the implementation for the members defined in that interface.
For example, here's an Employee
class that implements the IPerson
interface:
public class Employee : IPerson {
public string Name { get; set; }
public DateTime DateofBirth { get; set; }
public ushort Age() {
return (ushort)(DateTime.Now.Year - this.DateofBirth.Year);
Читать дальше