2. Contents
Inheritance
Calling base class constructors
The protected keyword
Dynamic binding; virtual and override
Polymorphism and assignment compatibility
All classes inherit from object
The need for down casts
Abstract classes
Examples
3. Inheritance
class Employee
{
int salary;
public Employee( ) { salary = 100; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee
{
string researchTopic;
}
In this code, the class Teacher extends the employee class. This means:
– Members of Employee like salary, Raise( ) are also members of
teacher (Inheritance).
– Objects of type teacher can be assigned to variables of type
employee (Polymorphism).
4. Inheritance
class Test
{
static void Main()
{
Teacher t = new Teacher();
t.Raise( ); // OK
Employee e1 = new Employee(); // OK
Employee e2 = new Teacher(); // OK
}
}
5. Calling base constructors
It is important for the derived class's constructor
to call the constructor of it's parent.
Calling the base constructor is done via the
base keyword.
Some useful rules:
If (a) The derived constructor (e.g Teacher)
doesn't call a base constructor, and (b) The
base has a parameterless constructor, then the
base parameterless constructor is called
automatically.
Otherwise, the derived constructor must call the
base constructor explicitly and give it
parameters.
6. Calling base constructors - 2
This code is correct, since Teacher's default constructor calls
Employee's default constructor
class Employee {
int salary;
public Employee( ) { salary = 100; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee {
string researchTopic;
}
7. Calling base constructors - 3
This code is also correct, since Teacher's Employee's default
constructor is still called.
class Employee {
int salary;
public Employee( ) { salary = 100; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee {
string researchTopic;
public Teacher() { }
}
8. Calling base constructors - 4
But this code is incorrect, since the compiler cannot know what
parameters to give to Employee's only constructor!
class Employee {
int salary;
public Employee(int s) { salary = s; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee {
string researchTopic;
public Teacher() { } // ???
}
9. Calling base constructors - 4
Now the code is correct, since all of Teacher's constructors give
the required parameters to the base class's constructors.
class Employee {
int salary;
public Employee(int s) { salary = s; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee {
string researchTopic;
public Teacher() : base(100) { } // OK
public Teacher(int _salary): base(_salary) {} // OK
}
10. Protected - 1
class Employee
{
int salary;
public Employee( ) { salary = 100; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee
{
string researchTopic;
public Teacher( )
{
salary = 500; // WRONG! 'salary' is private
}
}
11. Protected - 2
class Employee
{
protected int salary;
public Employee( ) { salary = 100; }
public void Raise( ) { salary += 50;}
}
class Teacher : Employee
{
string researchTopic;
public Teacher( )
{
salary = 500; // OK! 'salary' is protected
}
}
12. Overriding
A class like Teacher inherits all data members
and methods from it's parent class.
But what if some of Teacher's behavior is
different from employee?
For example, what if Raise( ) should increment
the salary by a different amount (say 51 instead
of 50?).
In this case the derived class can override the
method from its parent class.
But the parent class must allow overriding of
this method by making it virtual.
13. Overriding
class Employee {
int salary;
public Employee() { salary = 100; }
public virtual void Raise( ) { salary += 50;}
}
class Teacher : Employee {
string researchTopic;
public Teacher() { }
public override void Raise( ) { salary += 51; }
}
14. Dynamic binding
class Employee {
int salary;
public Employee() { salary = 100; }
public virtual void Raise( ) { salary += 50;}
}
class Teacher : Employee {
string researchTopic;
public Teacher() { }
public override void Raise( ) { salary += 51; }
}
class Test {
static void Main( ) {
Employee e = new Teacher( );
e.Raise( );
} }
Is e.salary now equal to 150 or 151?
15. Object...
All classes inherit from object. So an instance
of any class can be assigned to a variable of
type object, stored in an array of objects,
passed to functions that take objects....etc
Also, object includes functions like ToString( ),
which (a) Can be overriden and (b) Are used
by standard .net code like Console.WriteLine
and list boxes.
What about value types (which are not
classes)? When you assign them to objects
they are first copied into an object with a
reference. This is called boxing.
16. Downcasts
Employee e1, e2;
Teacher t1, t2, t3;
e1 = new Employee( ); // OK, same type
Teacher t1 = new Teacher( );
e1 = t1; // OK, 'Teacher' is a
// subtype of 'Employee'
Teacher t2 = e2; // WRONG!
Teacher t3 = (Teacher) e2; // OK for the compiler
The last line is a downcast. It means "assume e2 is really a
reference to a 'Teacher' object"
There will be a runtime check that this is the case, and an
exception will be thrown if e2 isn't the correct type. Otherwise
the program will go on normally.
Downcasts are sometimes needed, but are usually a sign of
bad design; use polymorphism instead.
17. Abstract classes
class Shape {
public virtual double GetArea() { ... }
}
ماذا نضع
class Square : Shape { هنا؟؟؟
double side;
public Square(double s) { side = s;}
public override double GetArea() { return side*side;}
}
class Circle : Shape {
double radius;
public Circle(double r) { radius = r;}
public override double GetArea()
{ return Math.PI * radius*radius;}
}
18. Abstract classes
abstract class Shape {
public abstract double GetArea();
}
class Square : Shape {
double side;
public Square(double s) { side = s;}
public override double GetArea() { return side*side;}
}
class Circle : Shape {
double radius;
public Circle(double r) { radius = r;}
public override double GetArea()
{ return Math.PI * radius*radius;}
}
19. Abstract classes
Abstract classes represent common concepts
between many concrete classes.
A class that has one or more abstract functions must
also be declared abstract.
You cannot create instances of abstract classes (but
you're free to create references whose types are
abstract classes).
If a class inherits from an abstract class, it can
become concrete by overriding all the abstract
methods with real methods. Now it can be
instantiated.
20. Extra: A simple dialog box...
To end the session, we'll show how to create a simple
dialog box that reads a name from the user...
21. Creating the dialog box...
Value Property Object
btnOk btnCancel btnOk AcceptButton Form
btnCancel CancelButton Form
txtName OK DialogResult btnOk
Cancel DialogResult btnCancel
22. Creating the dialog box...
In Form2:
public string GetName( )
{
return txtName.Text;
}
23. Using a dialog box...
In Form1
void btnGetName_Click(object sender, EventArgs e)
{
Form2 f = new Form2();
DialogResult r = f.ShowDialog( ); // Show modal
if(r == DialogResult.OK)
{
string name = f.GetName( );
lblResult.Text = f;
}
}