1 / 73

Creating and Managing Classes and Objects Defining and Using a Class class Circle { int radius;

Creating and Managing Classes and Objects Defining and Using a Class class Circle { int radius; double Area() { return Math.PI * radius * radius; } } you use the class keyword to define a new class

chouston
Download Presentation

Creating and Managing Classes and Objects Defining and Using a Class class Circle { int radius;

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Creating and Managing Classes and Objects Defining and Using a Class class Circle { intradius; double Area() { return Math.PI * radius * radius; } } you use the class keyword to define a new class The data and methods of the class occur in the body of the class between a pair of braces Circle c; // Create a Circle variable c = new Circle(); // Initialize it

  2. You can directly assign an instance of a class to another variable of the same type, like this: Circle c; c = new Circle(); Circle d; d = c; Controlling Accessibility You cannot access its radius field or call its Area method, which is why the class is not of much use • A method or field is private if it is accessible only from the inside of the class. To declare that a method or field is private, you write the keyword private before its declaration. • A method or field is public if it is accessible from both the inside and outside of the class. To declare that a method or field is public, you write the keyword public before its declaration.

  3. class Circle { private int radius; public double Area() { return Math.PI * radius * radius; } } Here radius is declared as a private field and is not accessible from outside the class. Radius is accessible from inside the Circle class. The Area method is inside the Circle class, so the body of Area has access to radius Another Example Illustrating Public & Private Fields • This time Area is declared as a public method and radius is declared as a private field:

  4. Creating a Shared Field Class circle { Private int radius; Public static intnumcircles = 0; Public circle() // default constructor { Radius = 0; Numcircles++; } Public circle(intinitialradius) // overloaded constructor { Radius = initialradius; Numcircles++; } } With this feature, you can create a single field that is shared among all objects created from a single class The static field NumCircles in the Circle class is incremented by the Circle constructor every time a new Circle object is created: Console.WriteLine("Number of Circle objects: {0}", Circle.NumCircles); NumCircles field increments every time a new instance is created. You access the NumCircles field by specifying the Circle class rather than a Circle object. For example:

  5. Copying Value Type Variables and Classes • Types such as int, float, double, and char are called value types • When you declare a variable as a value type, the compiler generates code that allocates a block of memory big enough to hold a corresponding value. • When you declare a Circle variable, the compiler does not generate code that allocates a block of memory big enough to hold a Circle; all it does is allot a small piece of memory that can potentially hold the address of (or a reference to) another block of memory containing a Crcle. • A class is an example of a reference type. Reference types hold references to blocks of memory. • inti = 42; // declare and initialize i • intcopyi = i; // copyi contains a copy of the data in i • i++; // incrementing i has no effect on copyi • Circle c = new Circle(42); • Circle refc = c;

  6. The at sign (@) in the Circle objects represents a reference to an address in memory:

  7. Using Nullable Types • The null value is useful for initializing reference types, but null is itself a reference, and you cannot assign it to a value type (For Example) • inti = null; // illegal • A nullable value type behaves in a similar manner to the original value type, but you can assign the null value to it. You use the question mark (?) to indicate that a value type is nullable, like this: • int? i = null; // legal

  8. Using ref and out Parameters static void DoIncrement(intparam) { param++; } static void Main() { intarg = 42; DoIncrement(arg); Console.WriteLine(arg); // writes as 42 not 43 } • when you pass an argument to a method, the corresponding parameter is initialized with a copy of the argument. This is true regardless of whether the parameter is a value type (such as an int), a nullable type (such as int?), or a reference type Creating ref Parameters • If you prefix a parameter with the ref keyword, the parameter becomes an alias for the actual argument rather than a copy of the argument. • 2. When using a ref parameter, anything you do to the parameter you also do to the original argument because the parameter and the argument both reference the same object.

  9. static void DoIncrement(ref intparam) // using ref { param++; } static void Main() { intarg = 42; // Without Initializing C G E DoIncrement(ref arg); // using ref Console.WriteLine(arg); // writes 43 } Here by using “ref” Keyword, Both the original argument and the passing argument names becomes same and when we print by using console statement, the incremented value gets printed.

  10. Out: Paramater • The out keyword is similar to the ref keyword. You can prefix a parameter with the out keyword so that the parameter becomes an alias for the argument. • When you pass an argument to an out parameter, you must also prefix the argument with the out keyword. • The keyword out is short for output. static void DoInitialize(out intparam) { param = 42; // If we dont initialize the param, such program does not compile at all. } static void Main() { intarg; // not initialized DoInitialize(out arg); Console.WriteLine(arg); // writes 42 }

  11. How Computer Memory Is Organized • Operating systems and language runtimes such as that used by C# frequently divide the memory used for holding data in two separate chunks, each of which is managed in a distinct manner. The Two chunks of memory are traditionally called the stack and the heap. • When you call a method, the memory required for its parameters and its local variables is always acquired from the stack and after use the memory will be released. • When you create an object (an instance of a class) by using the new keyword, the memory required to build the object is always acquired from the heap. STACK AND HEAP MEMORY • Stack memory is organized like a stack of boxes piled on top of one another. When a method is called, each parameter is put in a box that is placed on top of the stack.

  12. Heap memory is like a large pile of boxes strewn around a room rather than stacked neatly on top of each other. • Each box has a label indicating whether it is in use. When a new object is created, the runtime searches for an empty box and allocates it to the object. • The reference to the object is stored in a local variable on the stack. The System.ObjectClass • The significance of the System.Object class requires that it is used in inheritance • C# provides the object keyword as an alias for System.Object In the example, the variables c and o both refer to the same Circle object. Circle c; c = new Circle(42); object o; o = c;

  13. The Circle Variable and the object, both refer to the same value which will be stored in heap memory. The object will stored in the stack memory.

  14. Boxing & UnBoxing • Variables of type object can also refer to a value type. • In this two statements initialize the variable i (of type int, a value type) to 42 and then initialize the variable o (of type object, a reference type) to i: inti = 42; object o = i;

  15. inti = 42; object o = i; Inti=(int)i;

  16. Creating Value Types with Enumerations and Structures Defn:: An enumeration is a set of named integer constants. Declaring an Enumeration: You define an enumeration by using the enum keyword, followed by a set of symbols identifying the legal values that the type can have, enclosed between braces EXAMPLE:: enum Direction { East, West, North, South}; If the name of your enumeration is Direction, you can create variables of type Direction, fields of type Direction, and parameters of type Direction, as shown in this example: using System; public enum direction { East, West, North, South}; public class Program { public static void Main() { direction d=2; // Cannot implicit Convert type int to direction Console.WriteLine(d); // We can even set the value for enums & perform direction.east & explicit cast direction d } } Before you can read the value of an enumeration variable, it must be assigned a value.

  17. using System; // Another Example on Enumeration using System.Collections.Generic; using System.Linq; public enum direction { East=9, West=11, North=22, South=33}; public class Program { public static void Main() { direction d=direction.South; Console.WriteLine((int)d); // 33 is the output } }

  18. Structures: • Def: In C#, a structure is a value type data type. It helps you to make a single variable hold related data of various data types. • A structure can have its own fields, methods, and constructors. Declaring a Structure • To declare your own structure type, you use the struct keyword followed by the name of the type, followed by the body of the structure between opening and closing braces. • struct Time { public int hours, minutes, seconds; }

  19. struct Time { public Time(inthh, int mm, intss) { hours = hh % 24; minutes = mm % 60; seconds = ss % 60; } public int Hours() { return hours; } ... private int hours, minutes, seconds; } Here structure with constructors and methods to initialize and manipulate these fields, as shown in this example:

  20. Class versus Structure Classes and Structures have the following basic differences: • classes are reference types and structs are value types • structures do not support inheritance • structures cannot have default constructor • Classes are usually used for large amounts of data, whereas structs are usually used for smaller amounts of data. • A structure can't be abstract, a class can.

  21. What Is an Array? An array stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type stored at contiguous memory locations. Declaring Array Variables You declare an array variable by specifying the name of the element type, followed by a pair of square brackets, followed by the variable name. The square brackets signify that the variable is an array int[] pins; // Personal Identification Numbers Creating an Array Instance Arrays are reference types, regardless of the type of their elements. This means that an array variable refers to a contiguous block of memory holding the array elements on the heap, and this contiguous block of memory does not hold its array elements directly on the stack as a structure does.

  22. To create an array instance, you use the new keyword followed by the element type, followed by the size of the array you’re creating between square brackets. • For example, to create and initialize a new array of four integers for the pins variable declared earlier, • pins = new int[4]; The size of an array instance does not have to be a constant; it can be calculated at run time, as shown in this example: int size = int.Parse(Console.ReadLine()); int[] pins = new int[size];

  23. Initializing Array Variables When you create an array instance, all the elements of the array instance are initialized to a default value depending on their type. You can modify this behaviour and initialize the elements of an array to specific values if you prefer. You achieve this by providing a comma separated list of values between a pair of braces. int[] pins = new int[4]{ 9, 3, 7, 2 }; The number of values between the braces must exactly match the size of the array instance being created: int[] pins = new int[3]{ 9, 3, 7, 2 }; // compile-time error int[] pins = new int[4]{ 9, 3, 7 }; // compile-time error int[] pins = new int[4]{ 9, 3, 7, 2 }; // OK

  24. When you’re initializing an array variable, you can actually omit the new expression and the size of the array. The compiler calculates the size from the number of initializers and generates code to create the array. For example: int[] pins = { 9, 3, 7, 2 }; • Creating an Implicitly Typed Array • The element type when you declare an array must match the type of elements that you attempt to store in the array. • var names = new[]{"John", "Diana", "James", "Francesca"}; • In this example, the C# compiler determines that the names variable is an array of strings. • First, you omit the square brackets from the type; the names variable in this example is declared simply as var, and not var[]. • Second, you must specify the new operator and square brackets before the initializerlist.

  25. If you use this syntax, you must ensure that all the initializers have the same type. This example causes the compile-time error • “No best type found for implicitly typed array”: • var bad = new[]{"John", "Diana", 99, 100}; • * In the following code, the numbers array is an array of double because the constants 3.5 and 99.999 are both double, and the C# compiler can convert the integer values 1 and 2 to double values: • var numbers = new[]{1, 2, 3.5, 99.999}; • * Generally, it is best to avoid mixing types and hoping that the compiler will convert them for You.

  26. Array indexes are zero-based. The initial element of an array lives at index 0 and not index 1. An index value of 1 accesses the second element. • * All array element access is bounds-checked. If you specify an index that is less than 0 or greater than or equal to the length of the array, the compiler throws an IndexOutOfRangeException, as in this example: • try • { • int[] pins = { 9, 3, 7, 2 }; • Console.WriteLine(pins[4]); // error, the 4th and last element is at index 3 • } • catch (IndexOutOfRangeException ex) • { • ... • } • Iterating Through an Array. • All arrays are instances of the System.Array class in the Microsoft .NET Framework, and this class defines a number of useful properties and methods.

  27. Iterating Through an Array • All arrays are instances of the System.Array class in the Microsoft .NET Framework, and this class defines a number of useful properties and methods. • The following sample code writes the array element values of the pins array to the console: • int[] pins = { 9, 3, 7, 2 }; • for (int index = 0; index < pins.Length; index++) • { • int pin = pins[index]; • Console.WriteLine(pin); • } • Note Length is a property and not a method, which is why there are no parentheses when you call it.

  28. Two-Dimensional Arrays • The simplest form of the multidimensional array is the 2-dimensional array. A 2-dimensional array is a list of one-dimensional arrays. • A 2-dimensional array can be thought of as a table, which has x number of rows and y number of columns. Following is a 2-dimensional array, which contains 3 rows and 4 columns: • Initializing Two-Dimensional Arrays • Multidimensional arrays may be initialized by specifying bracketed values for each row. The Following array is with 3 rows and each row has 4 columns. • int [,] a = new int [3,4] { • {0, 1, 2, 3} , /* initializers for row indexed by 0 */ • {4, 5, 6, 7} , /* initializers for row indexed by 1 */ • {8, 9, 10, 11} /* initializers for row indexed by 2 */ • };

  29. An element in 2-dimensional array is accessed by using the subscripts. That is, row index and column index of the array. For example, intval= a[2,3]; The above statement takes 4th element from the 3rd row of the array. You can verify it in the above diagram.

  30. Understanding Parameter Arrays Using Array Arguments * Suppose you want to write a method to determine the minimum value in a set of values passed as parameters. One way is to use an array. * To find the smallest of several int values, you could write a static method named Min with a single parameter representing an array of int values:

  31. class Util • { • public static int Min(int[] paramList) • { • If (paramList == null || paramList.Length == 0) • { • throw new ArgumentException("Util.Min: not enough arguments"); • } • intcurrentMin = paramList [0]; • foreach (inti in paramList) • { • if (i < currentMin) • { • currentMin = i; • } • } • return currentMin; • } • } • To use the Min method to find the minimum of two int values, you write this: • int[] array = new int[2]; • array[0] = first; • array[1] = second; • int min = Util.Min(array);

  32. Declaring a params Array • You use the params keyword as an array parameter modifier. For example, here’s Min • again—this time with its array parameter declared as a params array: • class Util • { • public static int Min(paramsint[] paramList) • { • // code exactly as before • } • } • The effect of the params keyword on the Min method is that it allows you to call it by using • any number of integer arguments. • int min = Util.Min(first, second);

  33. Working with Inheritance • Inheritance in programming is all about classification—it’s a relationship between classes. • Here we take an example of Mammal and establish a relationship among a horse and a whale. • You declare that a class inherits from another class by using the following syntax: • class DerivedClass : BaseClass { • ... • } • The derived class inherits from the base class, and the methods in the base class also become part of the derived class. • In C#, a class is allowed to derive from, at most, one base class; a class is not allowed to derive from two or more classes. However, unless DerivedClass is declared as sealed.

  34. class DerivedSubClass : DerivedClass { • ... • } • Further Inheriting the DerivedClass is DerivedSubClass. • Methods in a class • The methods Breathe and SuckleYoung are common to all mammals. • class Mammal • { • public void Breathe() • { • ... • } • public void SuckleYoung() • { • ... • } • ... • }

  35. class Horse : Mammal • { • ... • public void Trot() • { • ... • } • } • class Whale : Mammal • { • ... • public void Swim() • { • ... • } • } • System.Object class is the root class of all classes. All classes implicitly derive from the System.Object class. • class Mammal : System.Object • { • ... • }

  36. Calling Base Class Constructors • class Mammal // base class • { • public Mammal(string name) // constructor for base class • { • ... • } • ... • } • class Horse : Mammal // derived class • { • public Horse(string name) • : base(name) // calls Mammal(name) • { • ... • } • ... • } • A derived class automatically contains all fields from the base class. These fields usually require initialization when an object is created. Remember that all classes have at least one constructor.

  37. It is good practice for a constructor in a derived class to call the constructor for its base class as part of the initialization. • You can specify the base keyword to call a base class constructor when you define a constructor for an inheriting class, as shown in previous slide: • If you don’t explicitly call a base class constructor in a derived class constructor, the compiler attempts to silently insert a call to the base class’s default constructor before executing the code in the derived class constructor. • Taking the earlier example, the compiler rewrites this: • class Horse : Mammal • { • public Horse(string name) • { • ... • } • ... • } • class Horse : Mammal • { • public Horse(string name) • : base() • { • ... • } • ... • }

  38. Assigning Classes • class Mammal • { • ... • } • class Horse : Mammal • { • ... • } • class Whale : Mammal • { • ... • } • ... • Horse myHorse = new Horse("Neddy"); // constructor shown earlier expects a name! • Whale myWhale = myHorse; // error – different types • So the following statements are legal: • Horse myHorse = new Horse("Neddy"); • Mammal myMammal = myHorse; // legal, Mammal is the base class of Horse • If you think about it in logical terms, all Horses are Mammals, so you can safely assign an • object of type Horse to a variable of type Mammal. The inheritance hierarchy means that you can think of a Horse simply as a special type of Mammal; it has everything that a Mammal has with a few extra bits defined by any methods and fields you add to the Horse class.

  39. Horse myHorse = new Horse("Neddy"); Mammal myMammal = myHorse; myMammal.Breathe(); // OK - Breathe is part of the Mammal class myMammal.Trot(); // error - Trot is not part of the Mammal class Declaring new Methods If you are defining a method for a class and that class is part of an inheritance hierarchy, sooner or later you are going to try to reuse a name that is already in use by one of the classes higher up the hierarchy. If a base class and a derived class happen to declare two methods that have the same signature, you will receive a warning when you compile the application. The method in the derived class masks (or hides) the method in the base class that has the same signature. For example, if you compile the following code, the compiler generates a warning message telling you that Horse.Talk hides the inherited method Mammal.Talk:

  40. class Mammal • { • ... • public void Talk() // assume that all mammals can talk • { • ... • } • } • class Horse : Mammal • { • ... • public void Talk() // horses talk in a different way from other mammals! • { • ... • } • } • The Talk method in the Horse class hides the Talk method in the Mammal class, and the Horse.Talk method will be called instead. • Using the new keyword like this does not change the fact that the two methods are completely unrelated and that hiding still occurs. It just turns the warning off. In effect, the new keyword says, “I know what I’m doing, so stop showing me these warnings.”

  41. Declaring Virtual Methods • A method that is intended to be overridden is called a virtual method. You should be clear • on the difference between overriding a method and hiding a method. Overriding a method is a mechanism for providing different implementations of the same method—the methods are all related because they are intended to perform the same task, but in a class-specific manner. • You can mark a method as a virtual method by using the virtual keyword. • namespace System • { • class Mammal • { • public virtual string ToString() • { • ... • } • ... • } • ... • }

  42. Declaring override Methods • class Horse : Mammal • { • ... • public override string ToString() • { • ... • } • } • The new implementation of the method in the derived class can call the original implementation of the method in the base class by using the base keyword, like this: • public override string ToString() • { • base.ToString(); • ... • }

  43. There are some important rules you must follow when declaring polymorphic methods: 1. You’re not allowed to declare a private method when using the virtual or override keyword. 2. The two method signatures must be identical—that is, they must have the same name, number, and type of parameters. In addition, both methods must return the same type. 3. The two methods must have the same level of access. For example, if one of the two methods is public, the other must also be public. 4. You can override only a virtual method. If the base class method is not virtual and you try to override it, you’ll get a compile-time error 5. If the derived class does not declare the method by using the override keyword, it does not override the base class method. In other words, it becomes an implementation of a completely different method that happens to have the same name. 6. An override method is implicitly virtual and can itself be overridden in a further derived class.

  44. Creating Interfaces and Defining Abstract Classes • Defining an Interface: • An Interface is also a user defined data type that contains methods without a method body ieAbstract methods. • You use the interface keyword instead of the class or struct keyword. Inside the interface, you declare methods exactly as in a class or a structure except that you never specify an access modifier (public, private, or protected), and you replace the method body with a semicolon. • interface IComparable • { • intCompareTo(object obj); • } • Implementing an Interface • To implement an interface, you declare a class or structure that inherits from the interface and that implements all the methods specified by the interface. • You could define the ILandBound interface that contains this method as follows: • interface ILandBound • { • intNumberOfLegs(); • }

  45. You could then implement this interface in the Horse class. You inherit from the interface and provide an implementation of every method defined by the interface. • class Horse : ILandBound • { • ... • public intNumberOfLegs() • { • return 4; • } • } • When you implement an interface, you must ensure that each method matches its corresponding interface method exactly, according to the following rules: • 1. The method names and return types match exactly. • 2. Any parameters (including ref and out keyword modifiers) match exactly. • 3. The method name is prefaced by the name of the interface. This is known as explicit • interface implementation and is a good habit to cultivate. • 4. All methods implementing an interface must be publicly accessible. However, if you are • using explicit interface implementation, the method should not have an access qualifier.

  46. A class can extend another class and implement an interface at the same time. In this case, C# does not denote the base class and the interface by using specific keywords. The base class is named first, followed by a comma, followed by the interface. The following example defines Horse as a class that is a Mammal but that additionally implements the ILandBound interface: interface ILandBound { ... } class Mammal { ... } class Horse : Mammal , ILandBound { ... }

  47. Referencing a Class Through Its Interface • You can reference an object by using a variable defined as an interface that its class implements. Taking the preceding example, you can reference a Horse • object by using an ILandBound variable, as follows: • Horse myHorse = new Horse(...); • ILandBoundiMyHorse = myHorse; // legal • This works because all horses are land-bound mammals, although the converse is not true, • and you cannot assign an ILandBound object to a Horse variable • Workingwith Multiple Interfaces • A class can have at most one base class, but it is allowed to implement an unlimited number of interfaces. A class must still implement all the methods it inherits from all its interfaces. • If an interface, structure, or class inherits from more than one interface, you write the interfaces in a comma-separated list. • class Horse : Mammal, ILandBound, IGrazable • { • ... • }

  48. Explicitly Implementing an Interface • * The examples you have seen so far have shown classes that implicitly implement an interface. • * If you revisit the ILandBound interface and the Horse class although the Horse class implements from the ILandBound interface, there is nothing in the implementation of the NumberOfLegs method in the Horse class that says it is part of the ILandBound interface: • * Suppose the Horse class implemented multiple interfaces. There is nothing to prevent multiple interfaces specifying a method with the same name, although they might have different semantics. • * Consider another Interface named Ijourney which also consists of a single method named NumberOfLegs. • * Now, if you implement this interface in the Horse class you have an interesting problem:

  49. Explicitly Implementing an Interface • interface ILandBound • { • intNumberOfLegs(); • } • Interface ONE • class Horse : ILandBound • { • ... • public intNumberOfLegs() • { • return 4; • } • } • One InetrafaceImplemented In Horse Class • interface IJourney • { • intNumberOfLegs(); • } • Interface TWO • class Horse : ILandBound, IJourney • { • ... • public intNumberOfLegs() • { • return 4; • } • } • Two Interfaces are Implemented In Horse Class

  50. To solve this problem and disambiguate which method is part of which interface implementation, you can implement interfaces explicitly. To do this, you specify which interface a method belongs to when you implement it, like this: • class Horse : ILandBound, IJourney • { • ... • intILandBound.NumberOfLegs() • { • return 4; • } • intIJourney.NumberOfLegs() • { • return 3; • } • }

More Related