Upload
hoangdiep
View
230
Download
8
Embed Size (px)
Citation preview
C# Programming: From Problem Analysis to Program Design
1
Advanced
Object-Oriented
Programming Features 11
C# Programming: From Problem Analysis to Program Design
4th Edition
2
Chapter Objectives
3
Chapter Objectives (continued)
C# Programming: From Problem Analysis to Program Design
4
Chapter Objectives (continued)
5
Object-Oriented Language
Features
6
Component-Based Development
Figure 11-1 Component-based development
7
Component-Based Development
(continued)
C# Programming: From Problem Analysis to Program Design
8
Component-Based Development
(continued)
9
Inheritance
→ →
10
Inheriting from the Object Class
C# Programming: From Problem Analysis to Program Design
11
Inheriting from Other .NET FCL Classes
System.Windows.Forms.Form
C# Programming: From Problem Analysis to Program Design
12
Inheriting from Other .NET FCL Classes
Base
class Derived
class Figure 11-3 Derived class
C# Programming: From Problem Analysis to Program Design
13
Creating Base Classes for Inheritance
Class Diagram:
Person - Student
14
Base class
Sub-class
(Derived)
Person Class (Base) 1 of 2
15
class Person { //data members private string lastName = "n.a"; private string firstName= "n.a"; private int age = 0; private string occupation = "n.a"; //Properties // Verbose style - Property for last name public string LastName { get { return lastName; } set { lastName = value; } } // Properties –using C# 7.0 style- Expression Bodied Method notation public string FirstName { get => firstName; set => firstName = value; } public int Age { get { return age; } set => age = Math.Abs(value); } public string Occupation { get { return occupation; } set => occupation = value; }
1
2
Person Class (Base) 2 of 2
16
// Constructor with zero arguments public Person() { } // Constructor with four arguments public Person( string lNameValue, string fNameValue, int ageValue) { LastName = lNameValue; FirstName = fNameValue; Age = ageValue; } //user-defined methods (new formatting feature C# 7.0) public override string ToString() { return string.Format( $"Person [ " + $"First= {FirstName} Last= {LastName} " + $"Age= {age} " + $"Ocuppation= {Occupation} ]"); } //a virtual method could be overridden by its derived sub-classes public virtual int GetSleepAmount() { return 8; } }
3
4
5
Student Class (Derived/Sub class) 1 of 2
17
class Student : Person { //data members private string major = "not declared yet"; private double gpa = 0.0; private int studentId = 0; //properties (bodied expressions) public string Major { get => major; set => major = value; } public double Gpa { get => gpa; set => gpa = value; } public int StudentId { get=> studentId; set=> studentId = value; } //constructors public Student() :base() { } public Student(string lNameValue,string fNameValue, int ageValue, int idValue, string majorValue, double gpaValue) :base(lNameValue, fNameValue, ageValue) { StudentId = idValue; Major = majorValue; Gpa = gpaValue; }
6
7
8
9
Student Class (Derived/Sub class) 2 of 2
18
//user-defined methods public override string ToString() { return string.Format( $"\nStudent [ ID= {StudentId} Major= {Major} GPA= {Gpa}" + $"\n\t" + base.ToString() + $" ]"); } public override int GetSleepAmount() { //return base.GetSleepAmount(); return 6; } }
10
11
Access Modifiers
19
Ancestor
private...
protected…
public…
Subclass
Only ancestor's
public & protected
members are visible
20
Creating Base Classes for Inheritance
class Person
{
//data members
private string lastName = "n.a";
private string firstName= "n.a";
private int age = 0;
private string occupation = "n.a";
All data members
are customarily
defined private.
Good practice!
These default values could be
used by zero-args constructor
Base class
All derived classes
will include these
four attributes 1
Properties (Verbose Style)
// Property for last name
public string LastName
{
get
{
return lastName;
}
set
{
lastName = value;
}
}
21
Private
data
member
Classic
verbose style
RHS of an
assignment
2
Properties (Compressed notation)
=>
(~Person() =>...
//Properties (using Expression Bodied Method's notation)
public string Occupation { get => occupation; set => occupation = value; }
public string LastName { get=> lastName; set=> lastName = value; }
public string FirstName { get => firstName; set => firstName = value; }
public int Age { get { return age; } set => age = Math.Abs(value); }
22
2
Public Access Modifier
LastName → lastName
23 Property field/data member
24
Creating Base Classes for Inheritance:
Constructors
// Constructor with zero arguments
public Person( )
{
}
// Constructor with four arguments
public Person (string lnameValue,string fnameValue,
int ageValue)
{
LastName = lnameValue;
FirstName = fnameValue;
Age = ageValue;
}
All the object's
data-members will used
their already declared
default values
Notice, constructor is a
method, has same name as
class (Person), has no return
type, and is overloaded
Properties
3
25
Overriding Methods
public override string ToString( ) // Defined in Person
public virtual int GetSleepAmt( ) // Defined in Person
•
•
•
virtual, abstract, override
override
26
Overriding Methods
• The Person class example overrides ToString()
//using string interpolation - new C# 6.0 formatting feature
public override string ToString()
{
return string.Format( $"\nPerson [ ID= {IdNumber} Age= {age} "
+ $"First= {FirstName} Last= {LastName} "
+ $"Ocuppation= {Occupation} ]");
}
Base class
ToString( )
method
ObjectPerson
Object
4
27
Virtual Methods (continued)
//a virtual method could be overridden by its derived sub-classes
public virtual int GetSleepAmount()
{
return 8;
}
HeavyCoffeeDrinker
5
28
Virtual Methods (continued)
Object
C# Programming: From Problem Analysis to Program Design
29
Creating Derived Classes
Derived Classes
class Student : Person
{
//data members
private string major = "not declared yet";
private double gpa = 0.0;
private int studentId = 0;
//properties (bodied expressions)
...
//constructors
public Student() :base() { }
C# Programming: From Problem Analysis to Program Design
30
Additional subclass
data members
Indicates which base
class constructor to use
Reference to base class
6
31
Calling the Base Constructor
//all-arguments constructor
public Student(string fnameValue, string lnameValue, int ageValue,
string majValue, string studentIdValue)
: base(lnameValue, fnameValue, ageValue) // calling base constructor
{
Major = majValue;
StudentId = studentIdValue;
} Use base constructor to
create a Person object
9
Student anotherStudent = new Student();
Person Student
new Student()
Calling the Base Constructor (cont)
32
Student s2 = new Student("Parker", "Peter", 21, 2001234, "CHEM", 4.0);
C# Programming: From Problem Analysis to Program Design
33
Calling Overridden Methods of the Base Class
return base.GetSleepAmt( ) // Calls GetSleepAmt( ) in
// parent class
34
Relationship
between the
Person and
Student
Classes
Figure 11-5 Inheritance class diagram
35
36
Abstract Classes
→
37
Abstract Classes
abstract
Person
public abstract class Person
...
38
Abstract Classes
Person new Person()
new Student()
39
Abstract Methods
40
Abstract Methods (continued)
[access modifier] abstract returnType MethodIdentifier
([parameter list]) ; // No { } included
Abstract Methods (continued)
Student
SetHobby
public override void SetHobby(string activityValue)
{
//assume List<string> listHobbies has been added to data members
listHobbies.Add(activityValue);
}
41
Defined in Person
Defined
in
Student
•
• public abstract void SetHobby(string activityValue);
Sealed Classes
Sealed
public sealed class Student
public class UndergraduateStudent : Student
42
Sealed Methods
public virtual void RaiseSalary(double incrementValue) {...}
public sealed override void RaiseSalary(double incrementValue) {...}
43
44
Partial Classes
partial
public abstract partial class Person
GeometricObject Example 1 of 9
45
GeometricObject Example 2 of 9
46
public abstract class GeometricObject { private string color = "White"; private DateTime dateCreated = new DateTime(2017, 12, 31, 23, 59, 59); private bool filled = false; // Properties (classic style) public string Color { get { return color; } set { string temp = value.ToUpper(); char firstLetter = temp[0]; color = firstLetter + temp.Substring(1).ToLower(); } } public DateTime DateCreated { get { return dateCreated; } private set { dateCreated = value; } } public bool Filled { get { return filled; } set { filled = value; } } //constructors public GeometricObject() { Color = "White"; Filled = true; DateCreated = DateTime.Now; }
1
2
public GeometricObject(string colorValue, bool filledValue) { Color = colorValue; Filled = filledValue; DateCreated = DateTime.Now; } //user-defined methods public override string ToString() { return string.Format($"GeometricObject [Color: {Color}, " + $"Filled:{Filled}, " + $"DateCreated:{DateCreated.ToString("yyy-MM-dd")}]"); } //Observe that the following two methods have no body! //Descendants of the GeometricObject class MUST implement them. public abstract double GetArea(); public abstract double GetArea(int numDecimals); public abstract double GetPerimeter(); public virtual int CalculateCost() //this VIRTUAL method may be overridden by descendants { //an arbitrary way to assess figure's cost int cost = 0; if (Color == "Gold" || Color=="Silver") { cost += 300; } if (filled) cost += 200; return cost; } } //GeometricObject
GeometricObject Example 3 of 9
47
3
4
5
6
class Circle : GeometricObject { //data member(s) private double radius = 0; //properties public double Radius { get { return radius; } set { radius = Math.Abs(value); } } //constructor(s) public Circle() : base() { Radius = 0; } public Circle(string colorValue, bool filledValue, double radiusValue) :base(colorValue, filledValue) { Radius = radiusValue; }
GeometricObject Example 4 of 9
48
7
8
//user-defined methods public override string ToString() { //showing two possible versions of the ToString() method int option = 1; switch (option) { case 1: //OPTION1. mixed message child + ancestor string ancestorMsg = base.ToString(); string childMsg1 = string.Format($"Circle [Radius: {Radius} ] "); return childMsg1 + " child of " + ancestorMsg; case 2: //OPTION2. only child's msg string childMsg2 = string.Format($"Circle [Radius:{Radius}, " + $"Color:{Color}, Filled:{Filled}, " + $"Created:{DateCreated} ]"); return childMsg2; } return "Circle"; } //The following three methods override the empty definition imposed by ancestor class. //The base class demanded that its ABSTRACT METHODS must be implemented by its children. public override double GetArea() { //NOTE: this method could be implemented instead as a read-only property //(see above defintion of property Area) return Math.PI * Math.Pow(Radius, 2); }
GeometricObject Example 5 of 9
49
9
10
public override double GetArea(int numDecimals) { //display area using a given number of decimal positions double area = Math.PI * Math.Pow(Radius, 2); string numFormat = "{0:N" + numDecimals + "}"; string strArea = string.Format(numFormat, area); return Convert.ToDouble(strArea); } public override double GetPerimeter() { return 2 * Math.PI * Radius; } }//Circle
GeometricObject Example 6 of 9
50
11
12
class Rectangle : GeometricObject { //data members private double height = 0; private double width = 0; //properties public double Width { get { return width; } set { width = value; } } public double Height { get { return height; } set { height = value; } } //constructors public Rectangle() : base() { Height = 0; Width = 0; }
GeometricObject Example 7 of 9
51
13
14
public Rectangle(double widthValue, double heightValue, string colorValue, bool filledValue) :base(colorValue, filledValue) { Width = widthValue; Height = heightValue; } //user defined methods public override string ToString() { return string.Format($"Rectangle [Height:{Height:N2}, Width:{Width:N2}, " + $"Color:{Color}, Filled:{Filled}, " + $"Created:{DateCreated} ]"); } //The following three methods override the empty definition imposed by ancestor class. //The base class demanded that its ABSTRACT METHODS must be implemented by its children. public override double GetArea() { return Height * Width; } public override double GetArea(int numDecimals) { //display area using a given number of decimal positions double area = Height * Width; string numFormat = "{0:N" + numDecimals + "}"; string strArea = string.Format(numFormat, area); return Convert.ToDouble(strArea); }
GeometricObject Example 8 of 9
52
15
16
public override double GetPerimeter() { return 2 * (Height + Width); } } //Rectangle
GeometricObject Example 9 of 9
53
17
54
Interfaces
55
Using .NET Interfaces
Icomparable
CompareTo()
this.CompareTo(other)
this other
this other
this other
this other
56
Using .NET Interfaces
public class Person : IComparable<Person>
public virtual int CompareTo(Person other)
{
if (this.age == other.age) return 0;
else if (this.age > other.age) return 1;
else return -1;
}
.
57
Using .NET Interfaces
Person p1 = new Person("Prince", "Diane", 22);
Person p2 = new Person();
if (p1.CompareTo(p2)!=0)
{
Console.WriteLine("Different people!");
}
58
Polymorphism
ToString( )
59
Generics
public class Stack<T>
{
private T[] items;
private int stackPointer = 0;
public Stack(int size)
{
items = new T[size];
}
…
Generic
Stack class
Generic Classes (continued) public T Pop( )
{
return items[--stackPointer];
}
public void Push(T anItem)
{
items[stackPointer] = anItem;
stackPointer++;
}
}
60
Generic Methods
61
62
Generic Methods (continued) public void SwapData <T> (ref T first, ref T second)
{ T temp; temp = first; first = second; second = temp;
}
//To call the method, specify the type following method name SwapData <string> (ref firstValue, ref secondValue);
Dynamic
C# Programming: From Problem Analysis to Program Design
63
Dynamic Data Type
64
Dynamic Data Type (continued)
dynamic intValue = 1000;
dynamic stringValue = "C#";
dynamic decimalValue = 23.45m;
dynamic aDate = System.DateTime.Today;
Console.WriteLine("{0} {1} {2} {3}" ,
intValue, stringValue, decimalValue, aDate);
1000C# 23.45 6/16/2013 12:00:00 AM
• Si
65
var Data Type
var
66
var Data Type (continued)
var someValue = 1000;
C# Programming: From Problem Analysis to Program Design
67
C# Programming: From Problem Analysis to Program Design
68
StudentGov
Application
Example
Figure 11-18 Problem specification for StudentGov example
C# Programming: From Problem Analysis to Program Design
69
StudentGov Application Example
(continued)
Table 11-1 Data fields organized by class
C# Programming: From Problem Analysis to Program Design
70
StudentGov Example (continued)
Figure 11-19 Prototype for StudentGov example
C# Programming: From Problem Analysis to Program Design
71
StudentGov Example (continued)
Figure 11-20 Class diagrams for StudentGov example
StudentGov Example (continued)
C# Programming: From Problem Analysis to Program Design
72
Figure 11-21 References added to StudentGov example
StudentGov Example (continued)
C# Programming: From Problem Analysis to Program Design
73
Figure 11-21 References added to StudentGov example (continued)
C# Programming: From Problem Analysis to Program Design
74
StudentGov Example (continued)
Table 11-2 PresentationGUI property values
C# Programming: From Problem Analysis to Program Design
75
StudentGov Example (continued)
Table 11-2 PresentationGUI property values (continued)
C# Programming: From Problem Analysis to Program Design
76
Table 11-2 PresentationGUI property values (continued)
StudentGov Example (continued)
C# Programming: From Problem Analysis to Program Design
77
Table 11-2 PresentationGUI property values (continued)
StudentGov Example (continued)
C# Programming: From Problem Analysis to Program Design
78
Figure 11-22 Setting the StartUp Project
StudentGov Example (continued)
C# Programming: From Problem Analysis to Program Design
79
StudentGov Application Example
(continued)
Figure 11-23 Part of the PresentationGUI assembly
C# Programming: From Problem Analysis to Program Design
80
StudentGov Application Example
(continued)
Figure 11-24 Output from StudentGov example
Coding Standards
C# Programming: From Problem Analysis to Program Design
81
Resources
C# Programming: From Problem Analysis to Program Design
82
83
Chapter Summary
84
Chapter Summary (continued)
C# Programming: From Problem Analysis to Program Design
85
Chapter Summary (continued)
86
APPENDIX Making Stand-Alone Components
C# Programming: From Problem Analysis to Program Design
87
APPENDIX
Dynamic Link Library (DLL)
88
Using Visual Studio to Create DLL Files
Figure 11-6 Creating a DLL component
C# Programming: From Problem Analysis to Program Design
89
Build Instead of Run to Create DLL
90
Build Instead of Run to Create DLL
Figure 11-7 Attempting to run a class library file
Build Instead of Run to Create
DLL (continued) using
using PersonNamespace;
C# Programming: From Problem Analysis to Program Design
91
92
Add Reference to Base Class
One of the
first things
to do is Add
a Reference
to the Parent
DLL
93
Add Reference to Base Class (continued)
Figure 11-9 Add Reference dialog box
Use
Browse
button
to
locate
DLL
94
Add Reference to Base Class
(continued)
Figure 11-10 Locating the Person.dll component
95
Adding a New Using Statement
public class Student : Person
96
Adding a New Using Statement
(continued)
public class Student : PersonNamespace.Person
using PersonNamespace; // Use whatever name you
// typed for the namespace for Person
Notice fully
qualified
name
C# Programming: From Problem Analysis to Program Design
97
Creating a Client Application to
Use the DLL
98
Creating a Client Application to
Use the DLL (continued)
Declaring an Object of the
Component Type
public class PresentationGUI : System.Windows.Forms.Form
{
private Student aStudent;
aStudent = new Student("123456789", "Maria", "Woo", "CS", "1111");
99
100
Creating a Client Application to
Use the DLL (continued)
Figure 11-13 PresentationGUI output referencing two DLLs
101
Using ILDASM to View the
Assembly
Using ILDASM to View the
Assembly (continued)
C# Programming: From Problem Analysis to Program Design
102
103
ILDASM to View the Assembly
Data
fields
.ctors are
constructors
Properties converted
to methods
IL code for
the method