Object-Oriented Programming and Polymorphism
Lesson1
Objects
- Abstraction = ability of programmatic objects to represent real-world things
- Class = template for object
- Object created -> copy of instance data defined by class created in memory and assigned to reference variable
- Each object independent of one another
Members
- Objects composed of members
- properties - data
- fields - data
- methods - actions object can perform
- events - notifications object receives
Object Model
- hierarchical organisation of objects contained and exposed within main object
- Car object contains Engine object, Wheel objects and Transmission object. Composition of subordinate objects affects how Car behaves - e.g. value of cylinders property of Engine modifies performance
Encapsulation
- Object implementation independent from its interface
- App interacts with object through its interface (public properties and methods)
- If interface remains constant, implementation can change without impacting app
- Internal object data should never be exposed - ensure fields are private
Polymorphism
-
Different classes providing different implementations of same public interface
-
e.g. Driver object can interact with both Car and Truck object through same interface
-
Interface Polymorphism
- Interface = behaviour contract
- Defines members to be implemented, but not how
- Object can implement multiple interfaces
- Many objects can implement same interface
- By convention interfaces start with I, e.g. IDrivable
-
Inheritance polymorphism
- Inheritance allows class to incorporate functionality of previously defined class, implementing different members as needed
- Can only inherit form one class (the base class)
- Inherited class has is-a relationship with base (e.g. PickupTruck is-a Truck)
- Can add additional members - extend functionality
- Can override base class members - modify functionality
Lesson 2
Overloading Members
- Multiple methods with same name but different signatures
- Access level and return type may vary
- Run time calls method matching signature provided - if no match then error!
Overloading Methods
public void DisplayMessage(int i)
{
MessageBox.Show(i.ToString());
}
public void DisplayMessage(string s)
{
MessageBox.show(s);
}
Overloading Operators
- For user defined types may be desirable to overload operator (e.g. complicated structure
public struct HoursWorked
{
float RegularHours;
float OvertimeHours;
}
- Overload operator using
public static _type_ operator _op_ (Arg1[, Arg 2])
{
...
}
- Unary operators - provide one argument
- Binary operators - provide two arguments (at least one same type)
- Must be static
- Must be public
- Must be defined within user defined type
public struct HoursWorked
{
float RegularHours;
float OvertimeHours;
public static HoursWorked operator + (HoursWorked a, HoursWorked b)
{
HoursWorked Result = new HoursWorked();
Result.RegularHours = a.RegularHours + b.RegularHours;
Result.OvertimeHours = a.OvertimeHours + b.OvertimeHours;
return Result;
}
public static HoursWorked operator + (HoursWorked a, int b)
{
HoursWorked Result = new HoursWorked();
Result.RegularHours = a.RegularHours + b;
return Result;
}
}
...
HoursWorked tot = new HoursWorked();
tot = Sunday + Monday;
Lesson 3
Interface Polymorphism
- Interface defined using interface keyword
- Member methods signature provided, but not access modifiers
- Can not defined fields
- Objects implementing interface are obliged to implement its methods, clients do not need to use them, implement event handlers, etc.
public interface IDrivable
{
void GoForward();
void Halt();
int DistanceTravelled();
int FuelLevel
{
get:
..
}
event System.EventHandler OutOfFuel;
}
- Method signature may indicate an interface is required
public void GoSomewhere(IDrivable v)
{
...
}
- Any object implementing required interface may be passed to method
- Object will be cast to appropriate interface - only interface members will be accessible within method implementation
Implement Interface
- Classes can implement multiple interfaces
- Specify interfaces as comma separated list
- Implementation below makes interface members available both via interface and class
public class Truck : IDrivable, IFuelBurning
{
public void GoForward(int Speed)
{
}
}
- Implementation below makes interface members available only via interface. No access modifier - has same level as member defined by class
public class Truck : IDrivable, IFuelBurning
{
void IDrivable.GoForward(int Speed)
{
}
}
Inheritance Polymorphism
- Instance of derived class can polymorphically behave as instance of its base
- If method requires Truck object can pass PickupTruck
- When cast to base, methods implemented by derived are unavailable
- Class inherit one base, multiple interfaces. List interfaces following base
public class FourWheelDrivePickupTruck : PickupTruck, IFourWheelDrive
{
...
}
- Stop class acting as base by others using sealed keyword
public sealed class AClass
{
}
Overriding Base Class Members
- Substitute new implementation for base class member
- Only override methods and properties
- Can not override fields and events
- New implementation must have same access level, signature and return type
public class SportsCar : Car
{
public override void GoForward(int Speed)
{
}
}
- Overridden member called in place of base version - regardless of context called in. If inherited class is cast to base and method called, new implementation still called. Type of object, not variable, determines which member called
- To override base member must be marked virtual
public virtual void OverrideMe()
{
...
}
Hiding Base Class Members
- Obscure base class members and replace with new implementation
- Must have same kind and have same signature as original
- Access level and return type can be different
- Use new keyword to indicate that base implementation should be hidden
- Can have interoperability implications (change to return type and accessibility) - only use where certain about compatibility
- Base implementation can be accessed on occasions - dependent on type of variable not object (unlike overriding)
- On inheritance hidden implementations not exposed - the base implementation is exposed
public class MyBaseClass
{
public string MyMethod(int I)
{
}
}
public class MyInheritedClass : MyBaseClass
{
internal new int MyMethod(int I)
{
}
}
Access Base Implementation
- Can access base implementation from inherited one using base keyword
public override void MyMethod()
{
base.MyMethod();
}
Abstract Classes and Members
-
Allows creation of base class providing some invariant functionality, whilst leaving implementation of others to inheriting classes
-
Abstract class can not be instantiated
-
Regular members of abstract class can be virtual (allowing inheriting classes to provide own implementations) or non-virtual (i.e. fixed)
-
Abstract members provide declaration, but not implementation
public abstract class AbstractClass
{
public abstract void GoForward(int I);
public abstract string Colour
{
get:
set:
}
}
- Inheriting classes must implement abstract members
- If inheriting class is abstract it is not required to implement abstract members