490 likes | 632 Views
Objects and Types. Classes and Structs. Classes and structs are essentially templates from which we can create objects. Each object contains data and has methods to manipulate and access that data. class PhoneCustomer { public const string DayOfSendingBill = “Monday”;
E N D
Classes and Structs • Classes and structs are essentially templates from which we can create objects. • Each object contains data and has methods to manipulate and access that data. • class PhoneCustomer • { • public const string DayOfSendingBill = “Monday”; • public int CustomerID; • public string FirstName; • public string LastName; • }
Structs differ from classes in the way that they are stored in memory and accessed (classes are reference types stored in the heap, structs are value types stored on the stack), and in some of the features (for example, structs don’t support inheritance)
struct PhoneCustomerStruct • { • public const string DayOfSendingBill = “Monday”; • public int CustomerID; • public string FirstName; • public string LastName; • }
For both classes and structs, you use the keyword new to declare an instance.
Class Members • Data Members • Data members are those members that contain the data for the class—fields, constants, and events • Data members can be either static (associated with the class as a whole) or instance (each instance of the class has its own copy of the data) • a class member is always an instance member unless it is explicitly declared as static. • Fields are any variables associated with the class. • Constants can be associated with classes in the same way as variables. • We declare a constant using the const keyword • Events are class members that allow an object to notify a caller whenever something noteworthy happens, such as a field or property of the class changing, or some form of user interaction occurring. The client can have code known as an event handler that reacts to the event.
Function Members • Function members are those members that provide some functionality for manipulating the data in the class. • They include methods, properties, constructors, finalizers, operators, and indexers. • Methodsare functions that are associated with a particular class. • They can be either instance methods or static methods, which provide more generic functionality that doesn’t require us to instantiate a class (like the Console.WriteLine() method).
Properties are sets of functions that can be accessed from the client in a similar way to the public fields of the class. • C# provides a specific syntax for implementing read and write properties on our classes, so we don’t have to jury-rig methods whose names have the words Get or Set embedded in them. • Since there’s a dedicated syntax for properties that is distinct from that for normal functions, the illusion of objects as actual things is strengthened for client code.
Constructorsare special functions that are called automatically when an object is instantiated. • They must have the same name as the class to which they belong, and cannot have a return type. • Constructors are useful for initializing the values of fields.
Finalizersare similar to constructors, but are called when the CLR detects that an object is no longer needed. • They have the same name as the class, preceded by a tilde (~). • C++ programmers should note that finalizers are used much less frequently than their nearest C++ equivalent, destructors, because the CLR handles garbage collection automatically. • Also, it is impossible to predict precisely when a finalizer will be called.
Operatorsare at their simplest are actions like + or -. When you add two integers you are, strictly speaking, using the + operator for integers. • However, C# also allows us to specify how existing operators will work with our own classes (operator overloading).
Indexersallow our objects to be indexed in the same way as an array or collection.
Method Vs Function • The term function member includes not only methods, but also other non-data members of a class or struct. • This includes indexers, operators, constructors, destructors, and also—perhaps somewhat surprisingly—properties
Declaring methods • [modifiers] return_type MethodName([parameters]) { // Method body }
Types of parameters • ref • Passing variables by value is the default. • We can, however, force value parameters to be passed by reference. • To do so, we use the ref keyword. • If a parameter is passed to a method, and if the input argument for that method is prefixed with the ref keyword, then any changes that the method makes to the variable will affect the value of the original object • Any variable must be initialized before it is passed into a method, whether it is passed in by value or reference. • Example:Program1.csRefPara.cs
out • When a method’s input argument is prefixed with out, that method can be passed a variable that has not been initialized. • The variable is passed by reference, so any changes that the method makes to the variable will persist when control returns from the called method. • If an out parameter isn’t assigned a value within the body of the function, the method won’t compile. • Example : out2.cs
Method Overloading • C# supports method overloading—several versions of the method that have different signatures (that is, the name, number of parameters, and parameter types). • However, C# does not support default parameters in the way that, say, C++ or Visual Basic do. • In order to overload methods, you simply declare the methods with the same name but different numbers or types of parameters:
Because C# does not support optional parameters, you will need to use method overloading to achieve the same effect: class MyClass { int DoSomething(int x) { // want 2nd parameter with default value 10 DoSomething(x, 10); } int DoSomething(int x, int y) { // implementation } }
Method Overloading Constraints • It is not sufficient for two methods to differ only in their return type. • It is not sufficient for two methods to differ only by virtue of a parameter having been declared as ref or out.
Properties • Properties are unusual in that they represent an idea that C# has taken from Visual Basic, not from C++/Java. • The idea of a property is that it is a method or pair of methods that are dressed to look like a field as far as any client code is concerned. • A good example of this is the Height property of a Windows Form. Suppose you have the following code: // mainForm is of type System.Windows.Forms mainForm.Height = 400; • On executing this code, the height of the window will be set to 400 and you will see the window resize on the screen. • Syntactically, the above code looks like we’re setting a field, but in fact we are calling a property accessor that contains code to resize the form.
To define a property in C#, we use the following syntax. public string SomeProperty { get{ return “This is the property value”; } set{ // do whatever; to set the property } }
It is possible to create a read-only property by simply omitting the set accessor from the property definition. • It is similarly possible to create a write-only property by omitting the get accessor.
Access modifiers for properties • Use public modifier for read only property and private or protected for set function.
Inlining • A method or property whose implementation simply calls another method or returns a field will almost certainly be inlined. • Note however that the decision of where to inline is made entirely by the CLR. • There is no way for you to control which methods are inlined, by using, for example, some keyword similar to the inline keyword of C++.
Constructors • The syntax for declaring basic constructors in C# is the same as in Java and C++. • We declare a method that has the same name as the containing class, and which does not have any return type: public class MyClass { public MyClass(){ } // rest of class definition }
In general, if you don’t supply any constructor, the compiler will just make up a default one for you behind the scenes. • It’ll be a very basic constructor that just initializes all the member fields by zeroing them out (null reference for reference types, zero for numeric data types, and false for bools). • Often, that will be adequate; if not, you’ll need to write your own constructor.
Constructors follow the same rules for overloading as other methods. • In other words, you can provide as many overloads to the constructor as you want, provided they are clearly different in signature: public MyClass() // zero-parameter constructor { // construction code } public MyClass(int number) // another overload { // construction code }
Note, however, that if you supply any constructors that take parameters, then the compiler will not automatically supply a default one. • This is only done if you have not defined any constructors at all. • Example: DefCon.cs
public class MyNumber { private int number; public MyNumber(int number) { this.number = number; } }
it is possible to define constructors as private or protected, so that they are invisible to code in unrelated classes too: public class MyNumber { private int number; private MyNumber(int number) // another overload { this.number = number; } }
This would actually make it impossible for MyNumber to be instantiated by outside code using the new operator (though you might write a public static property or method in MyNumber that can instantiate the class). • This is useful in two situations: ❑ If your class serves only as a container for some static members or properties, and therefore should never be instantiated ❑ If you want the class to only ever be instantiated by calling some static member function (this is the so-called class factory approach to object instantiation)
Static constructors • One novel feature of C# is that it is also possible to write a static no-parameter constructor for a class. • Such a constructor will only be executed once, as opposed to the constructors we’ve written so far, which are instance constructors, and are executed whenever an object of that class is created. class MyClass { static MyClass() { // initialization code } // rest of class definition }
One reason for writing a static constructor would be if your class has some static fields or properties that need to be initialized from an external source before the class is first used. • The .NET runtime makes no guarantees about when a static constructor will be executed, so you should not place any code in it that relies on it being executed at a particular time (for example, when an assembly is loaded). • Nor is it possible to predict in what order static constructors of different classes will execute. • However, what is guaranteed is that the static constructor will run at most once, and that it will be invoked before your code makes any reference to the class. • In C#, the static constructor usually seems to be executed immediately before the first call to any member of the class. • Example: StaticConst.cs
Calling constructors from other constructors • Constructor Initializer • It is used where you have several constructors in a class, perhaps to accommodate some optional parameters, for which the constructors have some code in common.
class Car { private string description; private uint nWheels; public Car(string model, uint nWheels) { this.description = model; this.nWheels = nWheels; } public Car(string model) { this.description = model; this.nWheels = 4; }
class Car { private string description; private uint nWheels; public Car(string model, uint nWheels) { this.description = model; this.nWheels = nWheels; } public Car(string model) : this(model, 4) { } }
Note that any constructor initializer is executed before the body of the constructor. • A C# constructor initializer may contain either one call to another constructor in the same class (using the syntax just presented) or one call to a constructor in the immediate base class (using the same syntax, but using the keyword base instead of this). • It is not possible to put more than one call in the initializer.
readonly Field • The readonly keyword gives a bit more flexibility than const, allowing for the case in which you might want a field to be constant but also need to carry out some calculations to determine its initial value. • The rule is that you can assign values to a readonly field inside a constructor, but not anywhere else. • It’s also possible for a readonly field to be an instance rather than a static field, having a different Objects and Types value for each instance of a class.
It’s also worth noting that you don’t have to assign a value to a readonly field in a constructor. • If you don’t do so, it will be left with the default value for its particular data type or whatever value you initialized it to at its declaration. • That applies to both static and instance readonly fields.
Structs • struct Dimensions • { • public double Length; • public double Width; • Dimensions(double length, double width) • { Length=length; Width=width; } • public int Diagonal • { • { • get • { • return Math.Sqrt(Length*Length + Width*Width); • } • } • } • }
Struct Vs Class ❑ Structs are value types, not reference types. • This means they are stored either in the stack or inline (if they are part of another object that is stored on the heap) and have the same lifetime restrictions as the simple data types. ❑ Structs do not support inheritance. ❑ There are some differences in the way constructors work for structs. • In particular, the compiler always supplies a default no-parameter constructor, which you are not permitted to replace. ❑ With a struct, you can specify how the fields are to be laid out in memory (see later on).
Structs Are Value Types • Although structs are value types, you can often treat them syntactically in the same way as classes. • For example, with our definition of the Dimensions class in the previous section, we could write: Dimensions point = new Dimensions(); point.Length = 3; point.Width = 6; • Note that because structs are value types, the new operator does not work in the same way as it does for classes and other reference types. • Instead of allocating memory on the heap, the new operator simply calls the appropriate constructor, according to the parameters passed to it, initializing all fields. • Indeed, for structs it is perfectly legal to write: Dimensions point; point.Length = 3; point.Width = 6; • If Dimensions was a class, this would produce a compilation error, because point would contain an uninitialized reference—an address that points nowhere, so we could not start setting values to its fields.
Structs follow the same rules as any other data type: everything must be initialized before use. • A struct is considered fully initialized either when the new operator has been called against it, or • when values have been individually assigned to all its fields. • A struct defined as a member field of a class is initialized when the containing object is initialized.
Structs and Inheritance • Structs are not designed for inheritance. • This means that it is not possible to inherit from a struct. • The only exception to this is that structs, in common with every other type in C#, derive ultimately from the class System.Object. • Hence, structs also have access to the methods of System.Object, and it is even possible to override them in structs—an obvious example would be overriding the ToString() method. • The actual inheritance chain for structs is that each struct derives from a class, System.ValueType, which in turn derives from System.Object. • ValueType does not add any new members to Object, but provides implementations of some of them that are more suitable for structs. • Note that you cannot supply a different base class for a struct • Every struct is derived from ValueType.
Constructors for Structs • You can define constructors for structs in exactly the same way that you can for classes, except that you are not permitted to define a constructor that takes no parameters. • There are some rare circumstances in which the .NET runtime would not be able to call a custom zero-parameter constructor that you have supplied. • Microsoft has therefore taken the easy way out and banned zero-parameter constructors for structs in C#.
struct Dimensions { public double Length = 1; // error. Initial values not allowed public double Width = 2; // error. Initial values not allowed } • Of course, if Dimensions had been declared as a class, this code would have compiled without any problems. • Example: Class1.cs
The Object Class • All .NET classes are ultimately derived from System.Object. • In fact, if you don’t specify a base class when you define a class, the compiler will automatically assume that it derives from Object. • As noted earlier, for structs this derivation is indirect: A struct is always derived from System.ValueType, which in turn derives from System.Object.
It means you also can access to a number of public and protected member methods that have been defined for the Object class. • These methods are available in all other classes that you define.