Вы находитесь на странице: 1из 31

Inheritance and

Polymorphism
MIS 21 – Introduction to Applications Development
Outline
➢ Review of inheritance
➢ Inheritance in C#
➢ Access modifiers
➢ Overriding methods
➢ Partial types
➢ Sealed classes
➢ Interfaces
➢ Abstract classes
Review of inheritance
➢ Inheritance:an OOP language feature that
allows for defining a class in terms of
another class
➢ A relationship between classes
➢ We say that a derived class (or subclass)
inherits from a base class (or superclass)
➢ Promotes the reusability of existing code
Review of inheritance
➢ Inheritance relationships produce a class hierarchy
➢ All types are ultimately derived from System.Object
System.Object

Shape

Circle Quadrilateral

Rectangle Trapezoid

Square
Inheritance in C#
➢ Suppose you had a BankAccount class:

public class BankAccount {


private int balance;

public int Balance {


get { return balance; }
}
public void Deposit(int amt) { balance += amt; }
public void Withdraw(int amt) { balance -= amt; }
}
Inheritance in C#
➢ And you wanted to create a CheckingAccount class:
public class CheckingAccount {
private int balance;
private int checksDrawn;

public int Balance {


get { return balance; }
}
public int ChecksDrawn {
get { return checksDrawn; }
}
public void Deposit(int amt) { balance += amt; }
public void Withdraw(int amt) { balance -= amt; }
public void DrawCheck(int amt) {
Withdraw(amt);
checksDrawn++;
}
}
Inheritance in C#
➢ You can reuse BankAccounts members with inheritance
➢ Syntax is: class DerivedClass : BaseClass

public class CheckingAccount : BankAccount {


private int checksDrawn;

public int ChecksDrawn {


get { return checksDrawn; }
}

public void DrawCheck(int amt) {


Withdraw(amt);
checksDrawn++;
}
}
Inheritance in C#
➢ Constructors are not inherited
➢ Use base to call a constructor of a class’s base
class
public class ParentClass {

public ParentClass(string n) {

public class ChildClass : ParentClass {

public ChildClass(string m)
: base(m) {

}
Inheritance in C#
public class BankAccount {
private string owner;
private double balance;
public BankAccount(string owner, int balance) {
this.owner = owner;
this.balance = balance;
}
public BankAccount(string owner) : this(owner, 0) {
}
}

public class CheckingAccount : BankAccount {


public CheckingAccount(string owner, int balance)
: base(owner, balance) {
}
public CheckingAccount(string owner) : this(owner, 0) {
}
}
Access modifiers
➢ Accessmodifiers are used to specify the declared
accessibility of a type or a member of a type
➢ Commonly used access modifiers:
➢ private
➢ public
➢ protected

➢ Other C# access modifiers


➢ internal
➢ protected internal
Access Modifiers - private
➢ private – Access is limited to the containing type
➢ Members of classes and structs are private by default
public class A {
private int x;
}
public class B {
public void DoSomething() {
A a = new A();
a.x = 17; // ERROR!
}
}
public class C : A {
public void DoSomething() {
x = 17; // ERROR!
}
}
Access modifiers - private
public class CheckingAccount : BankAccount {
private int checksDrawn;

public int ChecksDrawn {


get { return checksDrawn; }
}
public void DrawCheck(int amt) {
Withdraw(amt);
checksDrawn++;
}
}

➢ Why can’t you say balance -= amt instead of


withdraw(amt)?
➢ Because balance is a private field in BankAccount and cannot be
accessed by CheckingAccount (but is still inherited!)
Access modifiers - public
➢ public – Access is not restricted
➢ Members of enums and interfaces are public by default
public class A {
public int x;
}
public class B {
public void DoSomething() {
A a = new A();
a.x = 17; // OK
}
}
public class C : A {
public void DoSomething() {
x = 17; // OK
}
}
Access modifiers - protected
➢ protected – Access is limited to the containing type or types derived
from it

➢ Inherited protected members are also protected in the derived type


public class A {
protected int x;
}
public class B {
public void DoSomething() {
A a = new A();
a.x = 17; // ERROR!
}
}
public class C : A {
public void DoSomething() {
x = 17; // OK
}
}
Overriding methods
➢ Polymorphism allows you to use a variable for a
type to contain an object of any of its derived
types
➢ In C#, methods are not polymorphic by default
Overriding methods
public class Quad {
public string Shout() {
return "Quad!";
}
} Quad

public class Rect : Quad {


public string Shout() { Rect
return "Rectangle!";
}
Square
}

public class Square : Rect {


public string Shout() {
return "Square!";
}
}
Overriding methods
Quad[] q = new Quad[3];

q[0] = new Quad();


q[1] = new Rect();
q[2] = new Square();

Console.WriteLine( q[0].Shout() ); // Quad!


Console.WriteLine( q[1].Shout() ); // Quad!
Console.WriteLine( q[2].Shout() ); // Quad!

➢ q[1]and q[2] will inherit the Shout() method of the


Quad class because they did not override the
method.
Overriding methods
➢ Polymorphic methods must be declared as
virtual
➢ Virtual methods cannot be static or private
➢ To
override a virtual method, you must use the
override keyword
➢ Override methods are implicitly virtual
➢ An override method must match its associated virtual
method
➢ Override methods cannot be static or private
Overriding methods
public class Quad {
public virtual string Shout() {
return "Quad!";
}
} Quad

public class Rect : Quad {


public override string Shout() { Rect
return "Rectangle!";
}
Square
}

public class Square : Rect {


public override string Shout() {
return "Square!";
}
}
Overriding methods
➢ q[1]and q[2] will inherit the Shout() method of the
Quad class because they did not override the
method.
Quad[] q = new Quad[3];

q[0] = new Quad();


q[1] = new Rect();
q[2] = new Square();

Console.WriteLine( q[0].Shout() ); // Quad!


Console.WriteLine( q[1].Shout() ); // Rectangle!
Console.WriteLine( q[2].Shout() ); // Square!
Overriding methods
➢ Use new to inherit the method of the parent
public class Square : Rect {
public new string Shout() {
return "Square!";
}
}

Quad[] q = new Quad[3];

q[0] = new Quad();


q[1] = new Rect();
q[2] = new Square();

Console.WriteLine( q[0].Shout() ); // Quad!


Console.WriteLine( q[1].Shout() ); // Rectangle!
console.writeLine( q[2].Shout() ); // Rectangle!
Partial types
➢ Partial types allow the definition of a class, struct, or interface to be
split into multiple files

➢ Use the partial keyword

➢ The parts must agree with one another!

➢ The Windows Forms designer in Visual Studio uses partial types to


separate the GUI code from the event-handling code program logic
// PersonFields.cs // PersonProperties.cs

public partial class Person { public partial class Person {


private string name; public string Name {
} get { return name; }
set { name = value; }
}
}
Sealed classes
➢ Sealed classes cannot be derived from
➢ Use the sealed keyword
public sealed class Quad {

public class Rect : Quad { // ERROR!

}
Abstract classes
➢ An abstract class cannot be instantiated
➢ Abstract classes are intended to be used as a base class
➢ Use abstract keyword
➢ May contain abstract or non-abstract methods
➢ Abstract methods contain no implementation (but the non-
abstract methods do)
➢ Abstract methods are virtual
➢ Abstract methods can be overridden in derived classes (use
override)

➢ Abstract classes cannot be sealed


Abstract Classes
public abstract class Pet {
public abstract string Sound();
public string Buy() {
return "Take me home!";
} Pet
}

public class Dog : Pet { Dog Cat


public override string Sound() {
return "Woof!";
}
}

public class Cat: Pet{


public override string Sound() {
return "Meow!";
}
}
Abstract Classes
Pet[] p = new Pet[3];

p[0] = new Pet(); // Error


p[1] = new Dog();
p[2] = new Cat();

Console.WriteLine( p[1].Sound() ); // Woof!


Console.WriteLine( p[1].Buy() ); // Take me home!

Console.WriteLine( p[2].Sound() ); // Meow!


Console.WriteLine( p[2].Buy() ); // Take me home!
Interfaces
➢ An interface defines a contract
➢ An interface is a type
➢ May include methods, properties, indexers, events
➢ Any non-abstract class or struct implementing an interface must
support (i.e., define in code) all parts of the contract

➢ Interfaces provide no implementation


➢ Interfaces provide polymorphism
➢ In C#, interface members are implicitly public and
abstract
➢ Syntax: same as with inheritance (use colon)
Interfaces
public interface IPet { public class Cat : IPet {
string Sound(); public string Sound() {
string Buy(); return "Meow!";
} }
public string Buy() {
public class Dog : IPet { return "Pick me!";
public string Sound() { }
return "Woof!"; }
}
public string Buy() {
return "Buy me!";
}
}
Interfaces
IPet[] p = new IPet[3];

p[0] = new IPet(); // Error


p[1] = new Dog();
p[2] = new Cat();

Console.WriteLine( p[1].Sound() ); // Woof!


Console.WriteLine( p[1].Buy() ); // Buy me!

Console.WriteLine( p[2].Sound() ); // Meow!


Console.WriteLine( p[2].Buy() ); // Pick me!
Interfaces
➢ C# naming conventions for interfaces:
➢ Must start with a capital I (e.g., IEnumerable, ICollection)

➢ Inheritance and implementation rules with interfaces:


➢ A class or struct can implement multiple interfaces (use commas
to separate them)
➢ A class can inherit from only one class but can implement
multiple interfaces
➢ Interfaces can inherit from multiple interfaces
➢ If a base class implements an interface, classes derived from it
also inherently implement that interface
➢ If two implemented interfaces have the same method name, use
InterfaceName.Method to disambiguate
Abstract Classes and Interfaces
➢ Similarities between abstract classes and
interfaces:
➢ Neither can be instantiated
➢ Neither can be sealed

➢ Differences:
➢ Interfaces cannot contain any implementation
➢ Interfaces cannot declare non-public members
➢ Interfaces cannot extend non-interfaces