You are on page 1of 65

Chapter 4

Object Oriented Programming with C#

A Class is a customer user-defined type that is composed of data and functions that act on this data.

Employee
attributes: string fullName int empID float currPay Methods Employee() Employee(string fullName, int empID, float currPay) void GiveBonus(float amout) Void DisplayStats();

Method Overloading
When a class has a set of identically named members that differ by the number or type of parameters, the member in question is said to be overloaded. Eg: class Triangle { public void Draw( int x, int y, int height, int width); public void Draw( float x, float y, float height, float width); public void Draw(Point upperLeft, Point bottomRight); public Draw (Rect r); } When a class member is overloaded, the return type alone is not unique enough. public float GetX(); public int GetX();

Self Reference
this keyword This keyword is used whenever the reference is to be made to the current object. Static member functions of a type cannot use this keyword. public Employee(string FullName, int empID, float currPay) { this.fullName = FullName; this.empID = empID; this.currPay = currPay; this.empSSN = ssn; } public Employee(string fullName) : this(fullName, 3333, 0.0F) { }

Default public Interface


Set of public members that are directly accessible from an object variable.
Method visibility units that model the behavior of the class. Properties visibility Accessor and mutator functions Field Data visibility - Data

Type visibility which parts of the system can create type themselves. If not specified, it is assumed to be internal. public class HelloClass { } This would mean that all .Net assemblies can use this class. Any .NET type can be defined to have public or internal visibility.

using System; namespace Hellotypes { internal struct x { private int myX; public int GetMyX() { return myX;} public x(int x) {myX = x;} } internal enum Letters {a=0, b=1, c=2} public class HelloClass { public static int Main(string[] args) { X theX = new X(26); Console.WriteLine({0}\n{1}, theX.GetMyX(), Letters.b.toString()); return 0; } }

Pillars of OOP
Encapsulation: how well does this language hide the objects internal implementation? Inheritance: How does the language promote code reuse?
(Classical) Is-a Eg: Hexagon-shape-object has-a relationship Eg: car-radio

Polymorphism: How does this language let you treat related objects in a similar way?
Classical Base class defines a set of members that can be overridden by subclass. Eg; Draw Ad-hoc Late binding

Encapsulation
Black box programming An objects internal data should not be directly accessible from an object instance.
public private protected protected internal

Define the data fields as private


Define a pair of accessor and mutator methods Define a named property

using system; public class Department { private string departname; // Accessor. public string GetDepartname() { return departname; } // Mutator. public void SetDepartname( string a) { departname=a; } public static int Main(string[] args) { Department d = new Department(); d.SetDepartname("ELECTRONICS"); Console.WriteLine("The Department is :"+d.GetDepartname()); return 0; } }

public string Name { get { return fullName; } set { fullName = value;} } // Property for the empID. public int EmpID { get {return empID;} set { empID = value; } } // Property for the currPay. public float Pay { get {return currPay;} set {currPay = value;} }

class TimePeriod { private double seconds; public double Hours { get { return seconds / 3600; } set { seconds = value * 3600; } } } class Program { static void Main() { TimePeriod t = new TimePeriod(); // Assigning the Hours property causes the 'set' accessor to be called. t.Hours = 24; // Evaluating the Hours property causes the 'get' accessor to be called. System.Console.WriteLine("Time in hours: " + t.Hours);

Write a C# class Student with the following attributes usn (string) attendance (int) internalMarks (float) Create mutators and accessors to access usn and attendance. Create a property to access internalMarks. The attendance and internalMarks returned should be in percentage. (assume total no of classes = 60 and Max internal = 25) Write a main function that to demonstrate the usage.

C# Inheritance Support
using System; public class Employee { // protected data for kids. protected string fullName; protected int empID; private float currPay; }

namespace Employees { public class Manager : Employee { private ulong numberOfOptions; public ulong NumbOpts { get {return numberOfOptions;} set { numberOfOptions = value;} } } public class SalesPerson : Employee { protected int numberOfSales; public int NumbSales { get {return numberOfSales;} set { numberOfSales = value;} } } }

public static int Main(string[] args) { SalesPerson stan = new SalesPerson(); stan.EmpID = 100; stan.setFullName("Stan the Man"); stan.NumbSales = 42; stan.currPay; //Error return 0; }

public class Radio { public void TurnOn(bool on) { if(on) Console.WriteLine("Jamming..."); else Console.WriteLine("Quiet time..."); } }

public class Car { private int currSpeed; private int maxSpeed; private string petName; bool carIsDead; public Car() { maxSpeed = 100; carIsDead = false; } public Car(string name, int max, int curr) currSpeed = curr; maxSpeed = max; petName = name; carIsDead = false; } // A car has-a radio. private Radio theMusicBox = new Radio();

public void CrankTunes(bool state) { // Tell the radio play (or not). // Delegate request to inner object. theMusicBox.TurnOn(state); } public void SpeedUp(int delta) { // If the car is dead, just say so... if(carIsDead) { Console.WriteLine("{0} is out of order....", petName ); } else // Not dead, speed up. { currSpeed += delta; if(currSpeed >= maxSpeed) { Console.WriteLine("Sorry, {0} has overheated...", petName ); carIsDead = true; } else Console.WriteLine("=> CurrSpeed = {0}", currSpeed); } }

public class CarApp { public static int Main(string[] args) { // Make a car. Car c1; c1 = new Car("SlugBug", 100, 10); // Jam some tunes. Console.WriteLine("***** Turing on radio for SlugBug *****"); c1.CrankTunes(true); // Speed up. Console.WriteLine("\n***** Speeding up *****"); for(int i = 0; i < 10; i++) c1.SpeedUp(20); // Shut down. Console.WriteLine("\n***** Turing off radio for SlugBug *****"); c1.CrankTunes(false); return 0;

} }

Create a namespace college Base class: Person Attributes: name, address, Phone Derived class: Student Attributes: usn, branch, subjectsTaken Derived class: Teacher Attributes: subjectTaught, Helper class: Subject Attributes: SubjectName, MaxAtt, MaxIM

Create a Main function to


create an instance of a student, initialize it to your details. create an instance of a teacher, initialize it to a teachers details. Display all the details.

using System; namespace College { public class Person { protected string name; protected string address; protected string phone; public Person(string newName, string newAddress, string newPhone) { this.name = newName; this.address = newAddress; this.phone = newPhone; } public string getName() { return name; } public string getAddress() { return address; } public string getPhone() { return phone; } }

class Subject { private string subjectName; private int MaxAtt; private int MaxIM; public Subject(string newSubjectName, int newMaxAtt, int newMaxIM) { this.subjectName = newSubjectName; this.MaxAtt = newMaxAtt; this.MaxIM = newMaxIM; } public string getsubjectName() { return subjectName; } public int getMaxAtt() { return MaxAtt; } public int getMaxIM() { return MaxIM; } }

class Student : Person { private string usn; private string branch; private Subject subjectsTaken; public Student(string newName, string newAddress, string newPhone, string newUsn, string newBranch, Subject mySubject): base(newName, newAddress, newPhone) { this.usn = newUsn; this.branch = newBranch; this.subjectsTaken = mySubject; } public string getUsn() { return usn; } public string getBranch() { return branch; } public Subject getSubjectTaken() { return subjectsTaken; } }

class Teacher : Person { private Subject SubjectTaught; public Teacher(string newName, string newAddress, string newPhone, Subject mySubject) : base(newName, newAddress, newPhone) { this.SubjectTaught = mySubject; } public Subject getSubjectTaught() { return SubjectTaught; } }

class StudentApp { public static void Main() { Subject cSharp = new Subject("C#", 64, 25); Student stud1 = new Student("Sujatha", "Anandnagar", "9885655627", "1AT02CS007", "CSE" cSharp); Teacher t1 = new Teacher("Seema", "Hebbal", "080-765676", cSharp); Console.WriteLine("Student Name:" + stud1.getName()); Console.WriteLine("Student Address:"+stud1.getAddress()); Console.WriteLine("Student Phone:" + stud1.getPhone()); Console.WriteLine("Student USN:" + stud1.getUsn()); Console.WriteLine("Student branch:" + stud1.getBranch()); Console.WriteLine("Student Subject Taken:" + stud1.getSubjectTaken().getsubjectName()); Console.WriteLine("Teacher Name:" + t1.getName()); Console.WriteLine("Teacher Address:" + t1.getAddress()); Console.WriteLine("Teacher Phone:" + t1.getPhone()); Console.WriteLine("Teacher Subject Taught:" + t1.getSubjectTaught().getsubjectName()); Console.Read(); } } }

Output
Student Name:Sujatha Student Address:Anandnagar Student Phone:9885655627 Student USN:1AT02CS007 Student branch:CSE Student Subject Taken:C# Teacher Name:Seema Teacher Address:Hebbal Teacher Phone:080-765676 Teacher Subject Taught:C#

A C# property actually maps to a get_/set_ pair. (The reverse is not true)


Eg: public class Employee { private string empSSN; public string SSN { get { return empSSN;} set{ empSSN = value;} } //ERROR public string get_SSN() { return empSSN;} public string set_SSN(string val) {empsSN = val;} }

Read-Only and Write-Only properties


To configure a read-only property, simply build a property without a corresponding set block. If you wish to have write-only property, omit the get block.
public class Employee { private string empSSN; public Employee(string FullName, int empID, float currPay, string ssn) { this.fullName = FullName; this.empID = empID; this.currPay = currPay; this.empSSN = ssn; } public string SSN { get { return empSSN;}} }

Static properties
public class Employee { private static string companyName; public static string Company { get { return companyName;} set { companyName = value;} }

//Usage: Employee.Company = Infosys Inc; Console.WriteLine(The folks work at {0}, Employee.Company);

Static Constructor
Static constructors can be used to assign values to static data This assignment always happens by default. public class Employee {
private static string companyName; static Employee() { companyName = Infosys Inc; }

} //Usage Console.WriteLine (These folks work at {0}, Employee.Company);

Read-Only fields (Psudo encapsulation)


public class Employee { public readonly string SSNField; public Employee(string FullName, int empID, float currPay, string ssn) { this.fullName = FullName; this.empID = empID; this.currPay = currPay; this.empSSN = ssn; this.SSNField = ssn; } } //Error Employee brenner = new Employee(); brenner.SSNField = 666-66-666;

Preventing Inheritance
public sealed class PTSalesPerson : SalesPerson { Public PTSalesPerson(string fullName, int empID, float currPay, string ssn, int numberOfSales) { //Logic } } //Error Public class ReallyPTSalesPerson: PTSalesPerson

Containment and Delegation (has-a) relationship


Eg: Car, radio

Nested Type Definitions


public class Car { private class Radio { public void TurnOn(bool on) { if (on) Console.WriteLine(Jamming); else Console.WriteLine(Quiet Time); } } private Radio theMusicBox = new Radio(); } Nested type could be public or private (Not true for other types) Car$Radio

C# Polymorphic support
public class Employee { protected string fullName; protected int empID; protected float currPay; protected string empSSN; public Employee(string FullName, int empID, float currPay, string ssn) { this.fullName = FullName; this.empID = empID; this.currPay = currPay; this.empSSN = ssn; } public void GiveBonus(float amount) { currPay + = amount; } }

public class SalesPerson : Employee { protected int numberOfSales; public SalesPerson(string FullName, int empID, float currPay, string ssn, int numbOfSales) : base(FullName, empID, currPay, ssn) { numberOfSales = numbOfSales; } }

public class Manager : Employee { private ulong numberOfOptions;

public Manager(string FullName, int empID, float currPay, string ssn, ulong numbOfOpts) : base(FullName, empID, currPay, ssn) { // This point of data belongs with us! numberOfOptions = numbOfOpts; }
}

Manager Chucky = new Manager(Chucky, 92, 10000, 333-33-3333, 9000); Chucky.GiveBonus(); SalesPerson fran= new Manager(Fran, 93, 3000, 999-99-9999, 31); Chucky.GiveBonus();

public class Employee { protected string fullName; protected int empID; protected float currPay; protected string empSSN; public Employee(string FullName, int empID, float currPay, string ssn) { this.fullName = FullName; this.empID = empID; this.currPay = currPay; this.empSSN = ssn; } public virtual void GiveBonus(float amount) { currPay + = amount; } }

public class SalesPerson : Employee { protected int numberOfSales; public SalesPerson(string FullName, int empID, float currPay, string ssn, int numbOfSales) : base(FullName, empID, currPay, ssn) { numberOfSales = numbOfSales; } public override void GiveBonus(float amount) { int salesBonus = 0; if(numberOfSales >= 0 && numberOfSales <= 100) salesBonus = 10; else if(numberOfSales >= 101 && numberOfSales <= 200) salesBonus = 15; else salesBonus = 20; // Anything greater than 200. base.GiveBonus(amount * salesBonus); } }

public class Manager : Employee { private ulong numberOfOptions; public Manager(string FullName, int empID, float currPay, string ssn, ulong numbOfOpts) : base(FullName, empID, currPay, ssn) { // This point of data belongs with us! numberOfOptions = numbOfOpts; } public override void GiveBonus(float amount) { // Increase salary. base.GiveBonus(amount); // And give some new stock options... Random r = new Random(); numberOfOptions += (ulong)r.Next(500);

Manager Chucky = new Manager(Chucky, 92, 10000, 333-33-3333, 9000); Chucky.GiveBonus(300); SalesPerson fran= new Manager(Fran, 93, 3000, 999-99-9999, 31); Chucky.GiveBonus(200);

abstract Classes and abstract methods


You can directly create instances of Employee This is rather odd. Better design would be to prevent the ability to directly create a new Employee instance. Once a class is abstract, it may contain any number of abstract methods Abstract methods can be used when a method is to be defined that does not supply a default implementation. abstract public class Employee { //Logic }

Object

Void Draw()

Shape

Draw() Hexagon

Circle Draw()

namespace Shapes { public abstract class Shape { protected string petName; // Constructors. public Shape(){petName = "NoName";} public Shape(string s) { this.petName = s; }

public virtual void Draw() { Console.WriteLine(Shape.Draw); }


public string PetName { get {return this.petName;} set {this.petName = value;} } }

public class Circle : Shape { public Circle(){} // Call base class constructor. public Circle(string name): base(name){} // Circle does not override draw }

public class Hexagon : Shape { public Hexagon(){} public Hexagon(string name): base(name){} public override void Draw() { Console.WriteLine("Drawing " + PetName + " the Hexagon"); } }

public class ShapesApp { public static int Main(string[] args) { // The C# base class pointer trick. Shape[] s = {new Hexagon(), new Circle(), new Hexagon("Mick"), new Circle("Beth"), new Hexagon("Linda")};
for(int i = 0; i < s.Length; i++) { s[i].Draw(); } } }

namespace Shapes { public abstract class Shape { protected string petName; // Constructors. public Shape(){petName = "NoName";} public Shape(string s) { this.petName = s; } public abstract void Draw(); public string PetName { get {return this.petName;} set {this.petName = value;} } }

public class Circle : Shape { public Circle(){} // Call base class constructor. public Circle(string name): base(name){}
public override void Draw() { Console.WriteLine("Drawing " + PetName + " the Circle"); } }

public class Hexagon : Shape { public Hexagon(){} public Hexagon(string name): base(name){} public override void Draw() { Console.WriteLine("Drawing " + PetName + " the Hexagon"); } }

public class ShapesApp { public static int Main(string[] args) { // The C# base class pointer trick. Shape[] s = {new Hexagon(), new Circle(), new Hexagon("Mick"), new Circle("Beth"), new Hexagon("Linda")};
for(int i = 0; i < s.Length; i++) { s[i].Draw(); } } }

Versioning
C# allows derived classes to contain methods with the same name as base class methods. The base class method must be defined virtual.

If the method in the derived class is not preceded by new or override keywords, the compiler will issue a warning and the method will behave as if the new keyword were present.
If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class. If the method in the derived class is preceded with the override keyword, objects of the derived class will call that method rather than the base class method. The base class method can be called from within the derived class using the base keyword. The override, virtual, and new keywords can also be applied to properties, indexers, and events.

Versioning
public class MyBase { public virtual string Meth1() { return "MyBase-Meth1"; } public virtual string Meth2() { return "MyBase-Meth2"; } public virtual string Meth3() { return "MyBase-Meth3"; } }

class MyDerived : MyBase { // Overrides the virtual method Meth1 using the override keyword: public override string Meth1() { return "MyDerived-Meth1"; } // Explicitly hide the virtual method Meth2 using the new keyword public new string Meth2() { return "MyDerived-Meth2"; } // Because no keyword is specified in the following declaration // a warning will be issued to alert the programmer that // the method hides the inherited member MyBase.Meth3(): public string Meth3() { return "MyDerived-Meth3"; }

public static void Main() { MyDerived mD = new MyDerived(); MyBase mB = (MyBase) mD; System.Console.WriteLine(mB.Meth1()); System.Console.WriteLine(mB.Meth2()); System.Console.WriteLine(mB.Meth3()); }

Output

MyDerived-Meth1 MyBase-Meth2 MyBase-Meth3

Casting between Types


Implicit cast operations
//Manager is-a object Object frank = new Manager(Frank, 9, 40000, 111-11-1111, 5); //Manager is-a Employee Employee moonunit= new Manager(MoonUnit, 9, 40000, 111-15-1111, 5); //PTSalesPerson is a SalesPerson SalesPerson jill = new PTSalesPerson(Jill, 834, 4000, 145-11-1111, 5); First law of Casting: When two classes are related by a is-a relationship, it is always safe to reference a derived class using a base class reference.

public class TheMachine() { Public static void FireThisPerson(Employee e) { //Remove from database //Get key and pencil sharpener from fired Employee } } Employee moonunit= new Manager(MoonUnit, 9, 40000, 111-15-1111, 5); TheMachine.FireThisPerson(moonunit); SalesPerson jill = new PTSalesPerson(Jill, 834, 4000, 145-11-1111, 5); TheMachine.FireThisPerson(jill) Object frank = new Manager(Frank, 9, 40000, 111-11-1111, 5); TheMachine.FireThisPerson(frank); //Error You cannot treat a base type reference as a derived type without first performing an explicit cast !

TheMachine.FireThisPerson((Employee)frank);

Determining the Type of Employee


public class TheMachine { public static void FireThisPerson(Employee e) { if (e is SalesPerson) { Console.WriteLine(Lost a salesperson names {0}, e.getfullName()); Console.WriteLine({0} made {1} sales, e.GetFullName, ((SalesPerson)e).NumbSales); } if (e is Manager) { Console.WriteLine(Lost a Manager names {0}, e.getfullName()); Console.WriteLine({0} had {1} stock options, e.GetFullName, ((Manager)e).NumbOpts); }

public class TheMachine { public static void FireThisPerson(Employee e) { SalesPerson p = e as SalesPerson; if (p != null) { Console.WriteLine(Lost a salesperson names {0}, p.getfullName()); Console.WriteLine({0} made {1} sales, p.getFullName(), p.NumbSales); } else { Manager m = e as Manager; if (m != null) { Console.WriteLine(Lost a Manager names {0}, m.getfullName()); Console.WriteLine({0} had {1} stock options, m.getFullName(), m.NumbOpts); }}}}

Numerical casts
int x = 30000; byte b = (byte) x; //Loss of information, so cast explicitly byte b = 30; int x = b; //No loss

1.

The present population of two countries, namely My Country and Your Country are 817 million and 1.088 billion respectively. Their rates of population growth are 2.1% and 1.3% respectively. Write a C# program that determines the number of years until the population of My Country exceeds that of your country.
Enter two non-zero numbers. Write a program in C# to display the highest common factor and lowest common multiple.

2.

3.
4.

Write a program to display the Fibonacci series up to N in C#.


Design a C# program to define a structure: Student<USN, Name, Marks, Branch> Here, Branch is of type enum, with members <CSE, ISE, ELNS, EE, IT>. Add Appropriate constructor and also a method to hike the marks by 10% to only CSE students. Show creation of some student objects and the way to call these methods.

1. 2. 3. 4.

When a class has a set of identically named members that differ by the return types, the method is said to be overloaded (True/False) ________ keyword is used for self-reference in C# All static members of a class can refer to themselves using the this keyword. Point out the error in this code, if any.
class Employee { int empID; public Employee(int empID) { this.empID = empID;} public Employee():this(007){} }

5. 6. 7. 8. 9. 10. 11. 12.

What is a the default Public Interface of a Type? A Type can have the visibility ___________ or _________ _____________ pillar of OOP lets you extend the behavior of a class. What is Classical inheritance? What is Classical Polymorphism? Give one keyword in C# that enforces Encapsulation. What are accessor and mutator functions? Write a Property to provide readonly access this Datafield. private int empID;

13. 14. 15. 16. 17. 18. 19. 20. 21. 22.
23. 24.

The Properties map to _____ and __________ methods. A static constructor can be used to ___________________ How can read-only Fields be declared? Multiple inheritance is supported by C# (True/False) _________ keyword can be used to Prevent Inheritance. __________ relationship is also known as Containment/Delegation model. Nested Types can have visibility _________ A base class can enforce Polymorphism using the ________ keyword. What are abstract classes? ________ keyword is prefixed to a method is it needs to break its relationship with the base class. _________ operators are used to determine the type of an object. Numerical casts from smaller numerical type to higher numerical type should be explicit. (true/False)

You might also like