1 / 56

Set# 3 Advanced Concepts

Set# 3 Advanced Concepts . Inheritance:. Protected access modifier. Virtual Methods and Overriding. class Employee { public void CalculatePay() { Console.WriteLine("Employee.CalculatePay()"); } } class SalariedEmployee : Employee { new public void CalculatePay() { // public new …..

ting
Download Presentation

Set# 3 Advanced Concepts

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. Set# 3 Advanced Concepts Inheritance:

  2. Protected access modifier

  3. Virtual Methods and Overriding class Employee { public void CalculatePay() { Console.WriteLine("Employee.CalculatePay()"); } } class SalariedEmployee : Employee { new public void CalculatePay() { // public new ….. Console.WriteLine("SalariedEmployee.CalculatePay()"); } } class TestNewMethods { static void Main(string[ ] args) { Employee e = new Employee(); e.CalculatePay(); SalariedEmployee s = new SalariedEmployee(); s.CalculatePay(); } } This code work as expected, BUT???

  4. Virtual Methods and Overriding what happen if upcasting is done?? – Employee em=new SalariedEmployee(); – em. CalculatePay() ; //which one will be called. Answer: it will call the employee to calculate function (CalculatePay()). If a method with the same signature is declared in both base and derived classes, but the methods are not declared as virtual and override respectively, then the derived class version is said to hide the base class version. The result is that which version of a method gets called depends on the type of the variable used to reference the instance, not the type of the instance itself.

  5. Example, with upcasting using System; class Employee { public void CalculatePay() { Console.WriteLine("Employee.CalculatePay()"); } } class SalariedEmployee : Employee { new public void CalculatePay() { Console.WriteLine("SalariedEmployee.CalculatePay()"); } } class TestNewMethods { static void Main(string[ ] args) { Employee e = new SalariedEmployee();// upcasting e.CalculatePay(); SalariedEmployee s = new SalariedEmployee(); s.CalculatePay(); } }

  6. Polymorphism (overriding) • To solve the previous problem, use the two keywords: virtual and override. – use the virtual keyword on the base class’s method. – use the override keyword on the derived class’s implementation of that method. • Note that an override function must have the same access level (protected, public, and so on) as the virtual function it overrides. • Also, a virtual membercan’t be declared private because the member would then be impossible to override.

  7. Example using System; class Employee{ public string name; public Employee(string name){ this.name = name; } public virtual void CalculatePay(){ Console.WriteLine("Employee.CalculatePay called for {0}", name); } } class ContractEmployee : Employee{ public ContractEmployee(string name) : base(name){ } public override void CalculatePay(){ Console.WriteLine("ContractEmployee.CalculatePay called for {0}", name); } }

  8. class SalariedEmployee : Employee { public SalariedEmployee (string name) : base(name) { } public override void CalculatePay() { Console.WriteLine("SalariedEmployee.CalculatePay called for {0}",name); } } class TestPolymorphic { protected Employee[] employees; public void LoadEmployees() { employees = new Employee[2]; employees[0] = new ContractEmployee("Adam "); // upcasting employees[1] = new SalariedEmployee("ahmad");// upcasting } public void DoPayroll(){ for (int i = 0; i < employees.GetLength(0); i++){ employees[i].CalculatePay(); } }

  9. Example, cont… static void Main(string[] args){ TestPolymorphic t = new TestPolymorphic(); t.LoadEmployees(); t.DoPayroll(); } }

  10. Another version of TestPolymorphic class TestPolymorphic { static void Main(string[] args) { Employee[] employees; employees = new Employee[2]; employees[0] = new ContractEmployee("Adam "); // upcasting employees[1] = new SalariedEmployee("ahmad");// upcasting foreach (Employee e in employees) e.CalculatePay(); } }

  11. Abstract Class • Motivation: if you think no object of a class should be created, declare the class abstract • In general, an abstract class is a placeholder in a class hierarchy that represents a generic concept • The use of abstract classes is a design decision; it helps us establish common elements in a class that is too general to instantiate Vehicle Car Boat Plane

  12. Abstract Classes: Syntax • Use the modifier abstract on a class header to declare an abstract class, e.g.,abstract class Vehicle{ // … public abstract void Move();}class Car : Vehicle{ //… public void Move() { Console.WriteLine( “Car is moving!” ); }}abstract class StaffMember{ // … public abstract double Pay();}

  13. Abstract class The child of an abstract class must override the abstract methods of the parent, or it too must be declared abstract Only abstract classes can contain abstract methods An abstract class cannot be instantiated

  14. Sealed Classes C# allows classes and methods to be declared as sealed. In the case of a class, this means that you can’t inherit from that class. In the case of a method, this means that you can’t override that method.

  15. Parameters similar to ref parameters but no value is passed by the caller.

  16. out Parameter using System; class Test { void Read(out int first, out int next){ first = Console.Read(); // read '0' as character converted to Decimal = 48 next = Console.Read(); } void f(){ int first, next; Read(out first, out next); Console.WriteLine(first); // 48 Console.WriteLine(next);// 48 } public static void Main() { Test t = new Test(); t.f(); // f() is non static and main is static so we need an object of class to access } }

  17. Parameter passing Summary Two types of parameter passing: - Call by value: a modification on the formal argument has no effect on the actual argument - Call by reference: a modification on the formal argument can change the actual argument Depend on the type of a formal argument For C# simple data types, it is call-by-value Change to call-by-reference: ref or out The ref or out keyword is required in both method declaration and method call ref requires that the parameter be initialized before enter a method out requires that the parameter be set before return from a method

  18. Variable Number of Parameters void Add(out int sum, params ref int[] val) // Error

  19. Example class Test{ void Add(out int sum, params int[] val) { sum = 0; foreach (int i in val) sum = sum + i; } static void Main() { Test v = new Test(); int sum; v.Add(out sum, 3, 5, 2, 9); // sum == 19 Console.WriteLine(sum); } }

  20. Example 2 using System; class Test{ void Add(out string sum, params string[] val){ sum = “"; foreach (string i in val) sum = sum +" "+ i; } static void Main() { Test v = new Test(); string sum; v.Add(out sum, "This", "is","Just","an example"); // This is Just an example Console.WriteLine(sum); } }

  21. Class Constructors Example: using system; class Constructor1App { Constructor1App() { Console.WriteLine("I'm the constructor"); } public static void Main() { Console.WriteLine(" Constructor1 object..."); Constructor1App app = new Constructor1App(); } } • Purpose: initialize objects of the class • They have the same name as the class • There may be more then one constructor per class (overloaded constructors) • can take arguments • they do not return any value • it has no return type, not even void

  22. Constructors for Classes • this(…) Enables the current class to call another constructor defined within itself.

  23. Default Constructor

  24. Constructor Initializers • base(…) Enables you to call the current class’s base class constructor. • this(…) Enables the current class to call another constructor defined within itself. This is useful when you have overloaded multiple constructors and want to make sure that a default constructor is always called.

  25. Example class MyBase{ protected MyBase(int i) { } }; class MyDerived : MyBase{ int i; MyDerived(int i) : base(i) { } // call the constructor of base class };

  26. Example 2 using System; class BaseClass{ public BaseClass() { Console.WriteLine("Parameterless constructor called"); } public BaseClass(int foo) { Console.WriteLine("foo = {0}", foo); } } class DerivedClass : BaseClass{ public DerivedClass(int foo): base(foo){ Console.WriteLine("foo = {0}", foo); } } class BaseInitializer3{ public static void Main(){ Console.WriteLine("Main: DerivedClass object..."); DerivedClass derived = new DerivedClass(42); } }

  27. Example 3 using System; class CommaDelimitedFile{ public CommaDelimitedFile(string fileName) { Console.WriteLine("file name = {0}", fileName); } } enum TableId{ Customers,Suppliers, Vendors }; class DbTable : CommaDelimitedFile { public DbTable(TableId tableId): base(GetFileName(tableId)){ Console.WriteLine("tableId = {0}", tableId.ToString()); }

  28. Example, cont.. static string GetFileName(TableId tableId) { string fileName; switch(tableId) { case TableId.Customers: fileName = "customers.txt"; break; case TableId.Suppliers: fileName = "suppliers.txt"; break; case TableId.Vendors: fileName = "venders.txt"; break; default: throw new ArgumentException("Could not resolve table nam"); } return fileName; } } class BaseInitializer4{ public static void Main(){ Console.WriteLine("Customer Table object..."); DbTable derived = newDbTable(TableId.Customers); } }

  29. Destructors Is a method that’s called when an object is destroyed or goes out of scope. • Each class has only at most one destructor (also called finalizer) • Name of a destructor is the ~ character, followed by the class name • Destructors do not receive any arguments

  30. Overriding Inherited Properties using System; class CFile { public CFile(string fileName) { this.fileName = fileName; } protected string fileName; public virtual string FileName{ get { return fileName; } } } class CustomerTable : CFile{ public const string FILENAME = "customers.txt"; public CustomerTable() : base(FILENAME) { } public override string FileName{ get { return "Customers table"; } } }

  31. Overriding Inherited Properties, cont.. class OverrideProperties{ public static void Main() { CFilecustomerFile = new CFile(CustomerTable.FILENAME); Console.WriteLine("Customer file name = {0}", customerFile.FileName); CustomerTablecustomerTable = new CustomerTable(); Console.WriteLine("Customer file name = {0}", customerTable.FileName); } }

  32. Using Interface for Multiple Inheritance • Java/C# decision: single inheritance, meaning that a derived class can have only one parent class • To take the advantages of multiple inheritance, Java/C# defines interfaces, which give us the best aspects of multiple inheritance without the complexity

  33. C# Interface • A C# interface is a collection of methods, and properties • it can actually include other types of definitions • These methods and properties have no implementation • An interface is used to formally define a set of methods that a class will implement • An interface captures one aspect of a class • If class D is derived from class B, then you should feel comfortable in saying an object of D is also a B • If class D implements interface I, then you should feel comfortable in saying an object of D has I perspective

  34. Interfaces: Syntax interface is a reserved word public interface IComplexity { int Level { get; set; } } public interface IDisplayAble{ void Paint(); } // inherits Question, implements two interfaces class MultiChoice: Question, IComplexity, IDisplayAble { public void Paint() {...} public int Level {...} public string GetQuestionPart() {} public string GetAnswerPart() {}}

  35. Interfaces • Methods in an interface have public visibility by default • An interface cannot be instantiated • A class implements an interface by • stating so in the class header after : • A class can implement multiple interfaces: the interfaces are separated by commas • If a class asserts that it implements an interface, it must define all methods in the interface or the compiler will produce errors • A class that implements an interface can implement other methods as well

  36. Polymorphism via Interfaces • An interface name can be used as the type of an object reference variable IDoableobj; • The obj reference can be used to point to any object of any class that implements the IDoable interface • The version of doThis that the following line invokes depends on the type of object that obj is referring to: obj.doThis();

  37. public interface ISpeak { public void Speak(); } class Faculty {…} class Professor: Faculty, ISpeak { // public void Speak(){…} public void Pontificate() {…} } class Animal {} class Dog: Animal, ISpeak { // public void Speak(){ … } } ISpeak guest; guest = new Professor(); guest.Speak(); guest = Dog(); guest.Speak(); An Example ISpeak special; special = new Professor(); special.Pontificate(); // compiler error ISpeak special; special = new Professor(); ((Professor)special).Pontificate();

  38. Interfaces • Includes method declarations only. • It can contain methods, properties, indexers (next slide) none of which are implemented in the interface itself. • Interfaces, by definition, are abstract classes. • You don’t need to specify an access modifier such as public on an interface method. • Any class that implements an interface must define each and every member of that interface •Interfaces can extend other interfaces.

  39. Example interface ex { // Example method declaration bool Validate(); // Example read-only property declaration inttestProperty { get; } // Example indexer declaration string this[int index] { get; set; } } Indexer is sometimes referred to as a smart array, that is, a member that enables you to work with a class that’s logically an array of data. (Detailed discussion Later)

  40. example using System; public interface IDataBound{ void Bind(); } public class EditBox : IDataBound{ // implements interface // IDataBound implementation public void Bind() { Console.WriteLine("Binding to data store..."); } } class NameHiding1App{ // Main entry point public static void Main(){ Console.WriteLine(); EditBox edit = new EditBox(); Console.WriteLine("Calling EditBox.Bind()..."); edit.Bind(); Console.WriteLine(); IDataBound bound = (IDataBound)edit; // object of interface Console.WriteLine("Calling (IDataBound)" + "EditBox.Bind()..."); bound.Bind(); } } // see interfaceEx

  41. Avoiding Name Ambiguity – Explicitinterface implementation. using System; interfaceISerializable{ void SaveData();} interfaceIDataStore { void SaveData(); } class Test : ISerializable, IDataStore { void IDataStore.SaveData() { Console.WriteLine("[Test.SaveData] IDataStore "+ "implementation called"); } void ISerializable.SaveData() { Console.WriteLine("[Test.SaveData] ISerializable“ + "implementation called");} static void Main(){ Test t = new Test(); ISerializable a = (ISerializable)t; a.SaveData(); IDataStore b = (IDataStore)t; b.SaveData(); } }// see explicit

  42. interface

  43. Indexers class MyClass { public objectthis [int index] { get { // Return desired data. } set { // Set desired data. } } } • To use it: MyClasscls = new MyClass(); cls[0] = someObject; Console.WriteLine("{0}", cls[0]); Note: Indexers enable a class’s client to index into an object as though the object itself were an array.

  44. Indexer , example using System; class IntIndexer{ private string[] myData; public IntIndexer(int size) { myData = new string[size]; for (int i=0; i < size; i++){ myData[i] = "empty"; } } public stringthis[int pos] { get{ return myData[pos]; } set { myData[pos] = value; } } static void Main(string[] args) { int size = 10; IntIndexer myInd = new IntIndexer(size); myInd[9] = "Some Value"; // invoke set myInd[3] = "Another Value"; myInd[5] = "Any Value"; Console.WriteLine("\nIndexer Output\n"); for (int i=0; i < size; i++) { Console.WriteLine("myInd[{0}]: {1}", i,myInd[i]); } } }

  45. overloaded indexers using System; class OvrIndexer{ private string[] myData; private int arrSize; public OvrIndexer(int size) { arrSize = size; myData = new string[size]; for (int i=0; i < size; i++){ myData[i] = "empty"; } } public stringthis[int pos] { get { return myData[pos]; } set{ myData[pos] = value; } } public stringthis[string data]{ get{ int count = 0; for (int i=0; i < arrSize; i++){ if (myData[i] == data){ count++;} } return count.ToString(); } set{ for (int i=0; i < arrSize; i++){ if (myData[i] == data){ myData[i] = value; } } } }

  46. overloaded indexers static void Main(string[] args){ int size = 10; OvrIndexer myInd = new OvrIndexer(size); myInd[9] = "Some Value";// invoke set myInd[3] = "Another Value"; myInd[5] = "Any Value"; myInd["empty"] = "no value"; // invoke set Console.WriteLine("\nIndexer Output\n"); for (int i=0; i < size; i++) { Console.WriteLine("myInd[{0}]: {1}", i, myInd[i]); // invoke get } Console.WriteLine("\nNumber of \"no value\" entries: {0}", myInd["no value"]); // invoke get } }

  47. using System; class MonthlySales { int[] product1 = new int[12]; int[] product2 = new int[12]; public int this[int i] {// set method omitted => read-only get { return product1[i-1] + product2[i-1]; } } public int this[string month] { // overloaded read-only indexer get { switch (month) { case "Jan": return (product1[0] + product2[0]); case "Feb": return (product1[1] + product2[1]); default: return 1; } } } static void Main(string[] args){ MonthlySales sales = new MonthlySales(); Console.WriteLine(sales[1]+ sales["Feb"]); } } overloaded indexers.

  48. Abstract Properties and Indexers

More Related