320 likes | 484 Views
C# Classes and Inheritance. CNS 3260 C# .NET Software Development. Questions for Project 2. does the params array load the integers in sequentially (left to right, top to bottom)? yes Can you overload operator= or operator new? no Can I provide multiple overloads for one operator?
E N D
C# Classes and Inheritance CNS 3260 C# .NET Software Development
Questions for Project 2 • does the params array load the integers in sequentially (left to right, top to bottom)? • yes • Can you overload operator= or operator new? • no • Can I provide multiple overloads for one operator? • yes (and you should) • do I need to allow for any order of for the scalar operations (int + Matrix and Matrix + int) • It’s easy to do, but I only expect you to do one order (doesn’t matter to me which one it is)
Points to review • Immutable strings • Inheritance • Virtual
Immutable strings • Immutable means the string does not change when an operation is performed on it. • How do you change a string? • After the Replace function what does str contain? • “Welcome” • To do it right you must reassign to str. • str now contains: • “We-me” string str = “Welcome”; str.Replace(“lco”, “-”); string str = “Welcome”; str = str.Replace(“lco”, “-”);
Immutable strings • Passing an immutable string to a function • After calling ChangeMyString(string str), s1 contians “original” static void Main() { string s1 = "original"; ChangeMyString(s1); } static void ChangeMyString(string str) { str = "changed"; }
Immutable strings (again) • Passing an immutable string to a function • After calling ChangeMyString(ref string str), s1 contians “changed” static void Main() { string s1 = "original"; ChangeMyString(ref s1); } static void ChangeMyString(ref string str) { str = "changed"; }
Access specifiers • public: anyone can access • protected: only the class and derived classes can access • private: only the class can access
Review Overriding vs. Hiding public class Base { protected void fun1(){} protected virtual void fun2(){} } public class Derived : Base { protected new void fun1(){} protected override void fun2(){} } Hides base.fun1() Overrides base.fun1()
Overriding static void Main(){ Base b = new Derived(); b.fun1(); b.fun2();} Calls Base.fun1() Calls Derived.fun2() The vtable is used during runtime to resolve virtual function calls.
Overloading a method • Overloading vs. Overriding or hiding • Overriding: a derived class method covers (you can override or hide a base class method with a method of the same name.) • Overloading: Creating methods of the same name that take a different set of parameters • C# allows no default parameters • You may change access specifiers on various overloaded methods • You cannot overload on the return type alone • You can overload a base class method in a derived class • Only if the signatures match does it hide the base class method
Overloading Example public string GetValue(string str){ // do work here} public float GetValue(float f){ // do work here } public string GetValue(string str, int index){ // do work here }
Design consideration • Avoid duplicating code: public Token GetToken() { // do some work here return nextToken; } public Token GetToken(string name) { // don't duplicate work if you can help it Token t = GetToken(); if(t.Name != name) throw(new UnexpectedTokenException()); return t; }
Properties • Look like variables • Smell like variables • Taste like vegetables? • Used like variables • BUT are really methods • getters -- accessors • setters -- mutators
Property Example class MyPropDemo { private int myValue; public int MyValue { get{ return myValue; } //accessor set{ myValue = value; } //mutator } }
The value keyword • Implicit variable passed to properties and indexers • Type is the same as the return type of the property or indexer • May be used as a local-variable name or a field class MyPropDemo { private int myValue; public int MyValue { set { myValue = value; } // mutator get { return myValue; } // accessor } } type is int
Properties • Method in disguise • Allows us to change object state • Syntactical sugar • Allows to control access outside the class: class MyPropDemo { private int myValue; public int MyValue { set { myValue = value; } // mutator get { return myValue; } // accessor } }
Recursive Properties • Be careful with syntax not to recall the property from within the property class MyClass { private int myClassInt; public int MyClassInt { get { return MyClassInt; // Uh oh } set { myClassInt=value; } } }
virtual, abstract, static? • yes, yes and yes: public virtual int MyInt{ get { return myInt; } set { myInt=value; }} public static int MyInt { get { return myStaticInt; } set { myStaticInt=value; } } abstract public int MyInt { get; set; }
Why not just use public variables? • You can have extra functionality in a property if needed: public int MyInt { set { if(value < 0) throw(new SomeExceptionThatMakesSenseHere("Duh")); DoSomeWork(value); DontEvenHaveToInitializeAVariableIfYouDontWant(); } get{ return myInt; } }
Why not just use public variables? • Can have just a get or just a set: public int Count { get{return count;} }
Why not just use public variables? • Allows you to protect data in a multi-threaded situation: public int MyInt { set { lock(this) { myInt=value; } } }
Why not just use public variables? • Allows you to disguise complex lookups as simple or foreign variables as your own: private int Count { get { return ((SomeObject as SomeOtherObject)[i, j] as object).Container.Count; } }
What’s faster (See PropertyVSMemberSpeedTest demo)
New in version 2.0? • standard 2.7 working draft p292 allows for changing the access specifier on the get or set or both: class MyPropDemo { private int myValue; public int MyValue { get{ return myValue; } //accessor protected set{ myValue = value; } //mutator } }
A quick look at arrays • Arrays are stored in contiguous memory • Arrays are objects • Multidimensional arrays are either jagged or rectangular • Single dimensional array syntax: • All elements are zeroed (nulled for reference types) int[] intArray = new int[10];
Jagged Arrays • An array of arrays • 2nd rank can be an array of any length • Works the same for n dimensions • Index into the array: int[][] intArray = new int[10][]; for(int i=0; i<10; ++i) intArray[i] = new int[15+i]; intArray[3][5] = 100;
Rectangular Arrays • 2nd rank are all of the same length • Works the same for n dimensions • Index into the array: int[,] intArray = new int[10,15]; int[,,,] intArray = new int[10,15,6,5]; intArray[3,5] = 100; intArray[4,5,3,2] = 200;
Indexers class MyIndexDemo { private int[] iArray = {10,20,30,40,50}; public int this[int index] { get{ return iArray[index]; } set{ iArray[index] = value; } } } • Similar to operator[] in C++ • Similar to properties in C#
Indexer • Allows array-like access into a class • Good if you want you’re class to work as a collection • Can have get and set, or just one or the other • Can be overloaded • Can’t have ref or out parameters
Overloading an indexer class MyClass { System.Collections.Hashtable table = new System.Collections.Hashtable(); public object this[int i] { get { return table[i]; } set { table[i] = value; } } public object this[string i] { get { return table[i]; } set { table[i] = value; } } }
Jagged-style brackets class Class2 { private int[][] int2DArray = new int[10][]; public int[] this[int index] { get { return int2DArray[index]; } set { int2DArray[index] = value; } } void Main() { Class2 c = new Class2(); c[4][5] = 100; } }
Rectangular-style Indexer class Class3 { private int[,] int2DRectangularArray = new int[10, 10]; public int this[int x, int y] { get { return int2DRectangularArray[x, y]; } set { int2DRectangularArray[x, y] = value; } } void Main() { Class3 c = new Class3(); c[4, 5] = 100; } }