You are on page 1of 55

Object-Oriented Programming: Inheritance

and Polymorphism
 To understand inheritance and software
reusability.
 To understand the concepts of base classes
and derived classes.
 To understand member access modifier
protected and internal.
 To be able to use the base reference to
access base-class members
 To understand the use of constructors and
finalizers in base classes and derived classes.

2
 Inheritance is one of the main features of object-
oriented programming (OOP).
 Inheritance allows you to create a class that's based
on another class.
 Inheritance is a form of software reusability in which
classes are created by absorbing an existing class’s
data and behaviors and embellishing them with new
capabilities.
 Software reusability saves time during program
development.
 Inheritance encourages the reuse of proven and
debugged high-quality software, which increases the
likelihood that a system will be implemented
effectively.

3
 When inheritance is used, a derived class
inherits the properties, methods, and other
members of a base class.
 The objects that are created from the derived
class can use these inherited members.
 The derived class can also provide its own
members that extend the base class.
 In addition, the derived class can override
properties and methods of the base class by
providing replacement definitions for them.

4
 When creating a class, instead of writing
completely new instance variables and
methods, the programmer can designate that
the new class should inherit the class
variables, properties and methods of another
class.
 The previously defined class is called the
base class or superclass, and the new class is
referred to as the derived class or subclass.
 Once created, each derived class can become
the base class for future derived classes.

5
 A derived class, to which unique class variables,
properties and methods normally are added, is
often larger than its base class.
 A derived class is more specific than its base
class and represents a more specialized group of
objects.
 The derived class contains the behaviors of its
base class and additional behaviors.
 The direct base class is the base class from which
the derived class explicitly inherits.
 An indirect base class is inherited from two or
more levels up the class hierarchy.

6
 In the case of single inheritance, a class is
derived from one base class.
 C# does not support multiple inheritance
(which occurs when a class is derived from
more than one direct base class).
 Every object of a derived class is also an
object of that derived class’s base class.
 However, base-class objects are not objects
of their derived classes.
◦ For example, all cars are vehicles, but not all
vehicles are cars.

7
 We distinguish between the “is-a” relationship
and the “has-a” relationship.
 “Is-a” represents inheritance.
 In an “is-a” relationship, an object of a derived
class also can be treated as an object of its base
class.
◦ For example, a car is a vehicle.
 By contrast, “has-a” stands for composition.
 In a “has-a” relationship, a class object contains
one or more object references as members.
◦ For example, a car has a steering wheel.

8
 A derived class can access the non-private
members of its base class.
 Base-class members that should not be
accessible to properties or methods of a class
derived from that base class via inheritance are
declared private in the base class.
 A derived class can effect state changes in
private base-class members, but only through
non-private methods and properties provided in
the base class and inherited into the derived
class.
 Properties and methods of a derived class cannot
directly access private members of their base
class.

9
 One problem with inheritance is that a derived
class can inherit properties and methods it does
not need or should not have.
 Even when a base-class property or method is
appropriate for a derived class, that derived class
often requires the property or method to perform
its task in a manner specific to the derived class.
 In such cases, the base-class property or method
can be overridden (redefined) in the derived class
with an appropriate implementation.

10
 Every derived-class object “is an” object of its
base class, and one base class can have many
derived classes; therefore, the set of objects
represented by a base class typically is larger
than the set of objects represented by any of
its derived classes.
 For example, the base class Vehicle
represents all vehicles, including cars, trucks,
boats, bicycles and so on.
 By contrast, derived-class Car represents only
a small subset of all Vehicles.

11
 An object of one class “is an” object of another
class, as well.
 Example:
◦ A rectangle is a quadrilateral (as are squares,
parallelograms and trapezoids).
◦ Thus, class Rectangle can be said to inherit from class
Quadrilateral.
◦ In this context, class Quadrilateral is a base class, and
class Rectangle is a derived class.
◦ A rectangle is a specific type of quadrilateral, but it is
incorrect to claim that a quadrilateral is a rectangle—
the quadrilateral could be a parallelogram or some other
type of Quadrilateral.

12
 With inheritance, private members of a base class
are not accessible directly from that class’s
derived classes, but these private base-class
members are still inherited.
 All other base-class members retain their
original member access when they become
members of the derived class (e.g., public
members of the base class become public
members of the derived class, and protected
members of the base class become protected
members of the derived class).
 Through these inherited base-class members,
the derived class can manipulate private
members of the base class.

13
 Objects of all classes derived from a common
base class can be treated as objects of that base
class.
 A base class’s public members are accessible
anywhere that the program has a reference to an
object of that base class or one of its derived
classes.
 A base class’s private members are accessible
only within the body of that base class.
 A base class’s protected members can be
accessed only in that base class or in any classes
derived from that base class.

14
 A base class’s internal members can be accessed
only by objects declared in the same assembly.
 Note that an internal member is accessible in any
part of the assembly in which that internal
member is declared.
 Derived-class methods normally can refer to
public, protected and internal members of the
base class simply by using the member names.
 When a derived-class method overrides a base-
class member, the base-class member can be
accessed from the derived class by preceding the
base-class member name with keyword base,
followed by the dot operator (.).

15
Objectives
 To understand the concept of polymorphism.
 To understand how polymorphism makes
systems extensible and maintainable.
 To understand the distinction between
abstract classes and concrete classes.
 To learn how to create abstract classes,
interfaces and delegates.

16
 Polymorphism enables us to write programs that
handle a wide variety of related classes in a generic
manner and facilitates adding new classes and
capabilities to a system.
 With polymorphism, it is possible to design and
implement systems that are easily extensible.
 Programs can process objects of all classes in a class
hierarchy generically as objects of a common base
class.
 Furthermore, new classes can be added with little or
no modification to the generic portions of the
program, as long as those classes are part of the
inheritance hierarchy that the program processes
generically.

17
 Polymorphism is a feature of inheritance that lets you treat
objects of different subclasses that are derived from the
same base class as if they had the type of the base class.
◦ If, for example, Book is a subclass of Product, you can treat a
Book object as if it were a Product object.
 If you access a virtual member of a base class object and
the member is overridden in the subclasses of that class,
polymorphism determines the member that's executed
based on the object's type.
◦ For example, if you call the GetDisplayText method of a Product
object, the GetDisplayText method of the Book class is executed if
the object is a Book object.
 Polymorphism is most useful when you have two or more
derived classes that use the same base class.
 It allows you to write generic code that targets the base
class rather than having to write specific code for each
object type.

18
 An object of a derived class can be treated as
an object of its base class.
 A program can create an array of base-class
references that refer to objects of many
derived-class types.
 This is allowed despite the fact that the
derived-class objects are of different data
types.
 However, the reverse is not true— a base-
class object is not an object of any of its
derived classes.

19
 If a base-class reference refers to a derived-
class object, it is possible to convert the
base-class reference to the object’s actual
data type and manipulate the object as that
type.

20
// Point class represents an x-y coordinate pair.

using System;

// Point class definition implicitly inherits from Object


public class Point
{
// point coordinate
private int x, y;

// default constructor
public Point()
{
// implicit call to Object constructor occurs here
}
// constructor
public Point( int xValue, int yValue )
{
// implicit call to Object constructor occurs here
X = xValue;
Y = yValue;
}

21
// property X
public int X
{
get
{
return x;
}
set
{
x = value; // no need for validation
}

} // end property X

22
// property Y
public int Y
{
get
{
return y;
}

set
{
y = value; // no need for validation
}

} // end property Y

// return string representation of Point


public override string ToString()
{
return "[" + X + ", " + Y + "]";
}

} // end class Point

23
// Circle class that inherits from class Point.

using System;

// Circle class definition inherits from Point


public class Circle : Point
{
private double radius; // circle's radius

// default constructor
public Circle()
{
// implicit call to Point constructor occurs here
}

// constructor
public Circle( int xValue, int yValue, double radiusValue )
: base( xValue, yValue )
{
Radius = radiusValue;
}
24
// property Radius
public double Radius
{
get
{
return radius;
}

set
{
if ( value >= 0 ) // validate radius
radius = value;
}
} // end property Radius

// calculate Circle diameter


public double Diameter()
{
return Radius * 2;
}

25
// calculate Circle circumference
public double Circumference()
{
return Math.PI * Diameter();
}

// calculate Circle area


public virtual double Area()
{
return Math.PI * Math.Pow( Radius, 2 );
}

// return string representation of Circle


public override string ToString()
{
return "Center = " + base.ToString() +
"; Radius = " + Radius;
}

} // end class Circle


26
// Demonstrating inheritance and polymorphism.

using System;
using System.Windows.Forms;

// PointCircleTest class definition


class PointCircleTest
{
// main entry point for application.
static void Main( string[] args )
{
Point point1 = new Point( 30, 50 );
Circle circle1 = new Circle( 120, 89, 2.7 );

string output = "Point point1: " + point1.ToString() +


"\nCircle circle1: " + circle1.ToString();

// use 'is a' relationship to assign


// Circle circle1 to Point reference
Point point2 = circle1;

output += "\n\nCCircle circle1 (via point2): " +


point2.ToString();

27
// downcast (cast base-class reference to derived-class
// data type) point2 to Circle circle2
Circle circle2 = ( Circle ) point2;

output += "\n\nCircle circle1 (via circle2): " +


circle2.ToString();

output += "\nArea of circle1 (via circle2): " +


circle2.Area().ToString( "F" );

// attempt to assign point1 object to Circle reference


if ( point1 is Circle )
{
circle2 = ( Circle ) point1;
output += "\n\ncast successful";
}
else
{
output += "\n\npoint1 does not refer to a Circle";
}

MessageBox.Show( output, "Demonstrating the 'is a' relationship" );


} // end method Main

} // end class PointCircleTest


28
 Despite the fact that a derived-class object also “is a”
base-class object, the derived class and base-class
objects are different.
 Derived-class objects can be treated as if they were
base-class objects.
 This is a logical relationship, because the derived
class contains members that correspond to all
members in the base class, but the derived class can
have additional members.
 For this reason, assigning a base-class object to a
derived-class reference is not allowed without an
explicit cast.
 Such an assignment would leave the additional
derived-class members undefined.

29
 There are four ways to mix base-class
references and derived-class references with
base-class objects and derived-class objects:
1. Referring to a base-class object with a base-
class reference.
2. Referring to a derived-class object with a
derived-class reference.

30
3. Referring to a derived-class object with a base-
class reference is safe, because the derived-class
object is an object of its base class. However, this
reference can refer only to base-class members. If
this code refers to derived-class-only members
through the base-class reference, the compiler
reports an error.
4. Referring to a base-class object with a derived-
class reference generates a compiler error. To
avoid this error, the derived-class reference first
must be cast to a baseclass reference explicitly. In
this cast, the derived-class reference must
reference a derived-class object, or C# generates
an InvalidCastException.

31
 If class Rectangle is derived from class Quadrilateral,
then a Rectangle object is a more specific version of a
Quadrilateral object.
 Any operation (such as calculating the perimeter or
the area) that can be performed on an object of class
Quadrilateral also can be performed on an object of
class Rectangle.
 Such operations also can be performed on other
kinds of Quadrilaterals, such as Squares,
Parallelograms and Trapezoids.
 When a program invokes a derived-class method
through a base-class (i.e., Quadrilateral) reference,
C# polymorphically chooses the correct overriding
method in the derived class from which the object
was instantiated.

32
 With polymorphism, one method can cause
different actions to occur, depending on the
type of the object on which the method is
invoked.
 With polymorphism, the programmer can deal
in generalities and let the execution-time
environment concern itself with the specifics.
 The programmer can command a wide variety
of objects to behave in manners appropriate
to those objects, even if the programmer
does not know the objects’ types.

33
 Polymorphism promotes extensibility.
 Software used to invoke polymorphic
behavior is written to be independent of the
types of the objects to which messages (i.e.,
method calls) are sent.
 Thus, programmers can include into a system
additional types of objects that respond to
existing messages and can do this without
modifying the base system.

34
 When we think of a class as a type, we assume
that programs will create objects of that type.
 However, there are cases in which it is useful to
define classes for which the programmer never
intends to instantiate any objects.
 Such classes are called abstract classes.
 Because such classes normally are used as base
classes in inheritance hierarchies, we refer to
such classes as abstract base classes.
 These classes cannot be used to instantiate
objects, since abstract classes are incomplete.
 Derived classes must define the “missing pieces.”

35
 Abstract classes normally contain one or more
abstract methods or abstract properties, which are
methods and properties that do not provide
implementations.
 Derived classes must override inherited abstract
methods and properties to enable objects of those
derived classes to be instantiated.
 The purpose of an abstract class is to provide an
appropriate base class from which other classes may
inherit.
 Classes from which objects can be instantiated are
called concrete classes.
 Such classes provide implementations of every
method and property they define.

36
 A class is made abstract by declaring it with keyword
abstract.
 An inheritance hierarchy does not need to contain any
abstract classes, but many good object-oriented systems
have class hierarchies headed by abstract base classes.
 In some cases, abstract classes constitute the top few
levels of the hierarchy.
 Abstract classes must specify signatures for their abstract
methods and properties.
 C# provides keyword abstract to declare a method or
property as abstract.
 Methods and properties that are abstract do not provide
implementations—attempting to do so is a syntax error.

37
 Every concrete derived class must override all
base-class abstract methods and properties
(using keyword override) and provide concrete
implementations of those methods or properties.
 Any class with an abstract method in it must be
declared abstract.
 The difference between an abstract method and a
virtual method is that a virtual method has an
implementation and provides the derived class
with the option of overriding the method; by
contrast, an abstract method does not provide an
implementation and forces the derived class to
override the method (for that derived class to be
concrete).

38
 Defining an abstract method in a class that has
not been declared as abstract results is a syntax
error.
 Attempting to instantiate an object of an abstract
class results in a compilation error.
 Failure to override an abstract method in a
derived class is a syntax error, unless the derived
class also is an abstract class.
 An abstract class can have instance data and
non-abstract methods (including constructors),
 which are subject to the normal rules of
inheritance by derived classes.

39
 Although we cannot instantiate objects of
abstract base classes, we can use abstract
base classes to declare references; these
references can refer to instances of any
concrete classes derived from the abstract
class.
 Programs can use such references to
manipulate instances of the derived classes
polymorphically.

40
// Demonstrate a shape hierarchy using an abstract base class.
using System;
public abstract class Shape
{
// return Shape's area
public virtual double Area()
{
return 0;
}
// return Shape's volume
public virtual double Volume()
{
return 0;
}
// return Shape's name
public abstract string Name
{
get;
}
}
41
// Point2 inherits from abstract class Shape and represents
// an x-y coordinate pair.
using System;

// Point2 inherits from abstract class Shape


public class Point2 : Shape
{
private int x, y; // Point2 coordinates

// default constructor
public Point2()
{
// implicit call to Object constructor occurs here
}

// constructor
public Point2( int xValue, int yValue )
{
X = xValue;
Y = yValue;
}

42
// property X
public int X
{
get
{
return x;
}
set
{
x = value; // no validation needed
}
}
// property Y
public int Y
{
get
{
return y;
}
set
{
y = value; // no validation needed
}
}
43
// return string representation of Point2 object
public override string ToString()
{
return "[" + X + ", " + Y + "]";
}
// implement abstract property Name of class Shape
public override string Name
{
get
{
return "Point2";
}
}
} // end class Point2

44
// Circle2 inherits from class Point2 and overrides key
members.
using System;

// Circle2 inherits from class Point2


public class Circle2 : Point2
{
private double radius; // Circle2 radius

// default constructor
public Circle2()
{
// implicit call to Point2 constructor occurs here
}

// constructor
public Circle2( int xValue, int yValue, double radiusValue )
: base( xValue, yValue )
{
Radius = radiusValue;
}

45
// property Radius
public double Radius
{
get
{
return radius;
}

set
{
// ensure non-negative radius value
if ( value >= 0 )
radius = value;
}
}

// calculate Circle2 diameter


public double Diameter()
{
return Radius * 2;
}
// calculate Circle2 circumference
public double Circumference()
{
return Math.PI * Diameter();
}

46
// calculate Circle2 area
public override double Area()
{
return Math.PI * Math.Pow( Radius, 2 );
}

// return string representation of Circle2 object


public override string ToString()
{
return "Center = " + base.ToString() +
"; Radius = " + Radius;
}

// override property Name from class Point2


public override string Name
{
get
{
return "Circle2";
}
}

} // end class Circle2

47
// Cylinder2 inherits from class Circle2 and overrides key
members.
using System;

// Cylinder2 inherits from class Circle2


public class Cylinder2 : Circle2
{
private double height; // Cylinder2 height

// default constructor
public Cylinder2()
{
// implicit call to Circle2 constructor occurs here
}
// constructor
public Cylinder2( int xValue, int yValue, double radiusValue,
double heightValue ) : base( xValue, yValue, radiusValue )
{
Height = heightValue;
}

48
// property Height
public double Height
{
get
{
return height;
}

set
{
// ensure non-negative height value
if ( value >= 0 )
height = value;
}
}

// calculate Cylinder2 area


public override double Area()
{
return 2 * base.Area() + base.Circumference() * Height;
}

49
// calculate Cylinder2 volume
public override double Volume()
{
return base.Area() * Height;
}
// return string representation of Circle2 object
public override string ToString()
{
return base.ToString() + "; Height = " + Height;
}

// override property Name from class Circle2


public override string Name
{
get
{
return "Cylinder2";
}
}

} // end class Cylinder2

50
// Demonstrates polymorphism in Point-Circle
Cylinder hierarchy.
using System;
using System.Windows.Forms;

public class AbstractShapesTest


{
public static void Main( string[] args )
{
// instantiate Point2, Circle2 and Cylinder2 objects
Point2 point = new Point2( 7, 11 );
Circle2 circle = new Circle2( 22, 8, 3.5 );
Cylinder2 cylinder = new Cylinder2( 10, 10, 3.3, 10 );

// create empty array of Shape base-class references


Shape[] arrayOfShapes = new Shape[ 3 ];

// arrayOfShapes[ 0 ] refers to Point2 object


arrayOfShapes[ 0 ] = point;

51
// arrayOfShapes[ 1 ] refers to Circle2 object
arrayOfShapes[ 1 ] = circle;

// arrayOfShapes[ 1 ] refers to Cylinder2 object


arrayOfShapes[ 2 ] = cylinder;

string output = point.Name + ": " + point + "\n" +


circle.Name + ": " + circle + "\n" +
cylinder.Name + ": " + cylinder;

// display Name, Area and Volume for each object


// in arrayOfShapes polymorphically
foreach( Shape shape in arrayOfShapes )
{
output += "\n\n" + shape.Name + ": " + shape +
"\nArea = " + shape.Area().ToString( "F" ) +
"\nVolume = " + shape.Volume().ToString( "F" );
}
◦ MessageBox.Show( output, "Demonstrating Polymorphism" );
}
}

52
 Variables can be declared const and readonly to
indicate that they cannot be modified after they are
initialized.
 Variables declared with const must be initialized
when they are declared; variables declared with
readonly can be initialized in the constructor, but
cannot be changed after they are initialized.
 The keyword sealed provides is applied to methods
and classes to prevent overriding and inheritance.
 A method that is declared sealed cannot be
overridden in a derived class.
 Methods that are declared static and methods that
are declared private are implicitly sealed.

53
 If a method is declared sealed, it cannot be overridden in
derived classes.
 Method calls must not be sent polymorphically to objects
of those derived classes.
 The method call still may be sent to derived classes, but
they will respond identically, rather than polymorphically.
 Remember that a method cannot be overridden (using the
keyword override) if it is not declared either virtual or
abstract.
 Therefore, keyword sealed is not needed for these cases.
 Keyword sealed is used for methods that have been
overridden, but that we do not want to be overridden in
derived classes.

54
 A class that is declared sealed cannot be a base class (i.e.,
a class cannot inherit from a sealed class).
 All methods in a sealed class are sealed implicitly.
 A sealed class is the opposite of an abstract class in
certain ways.
 An abstract class cannot be instantiated—other classes
derive from the abstract base class and implement the
base class’s abstract members.
 A sealed class, on the other hand, cannot have any derived
classes.
 This relationship is similar with regard to methods. An
abstract method must be overridden in a derived class.
 A sealed method cannot be overridden in a derived class.

55

You might also like