Title: Overview
1 2Essential features
- C replaced by C
- Simplify software development
- A new component model
- Simplify software upgrade
- Web services
- Simplify distributed computing
3C
- The core language used in .NET
- Similar to Java, plus some features from C
- Main features
- C-pointer replaced by reference (no more , ,
-gt) - User-defined type (OO class and object)
- Managed heap (system deletes memory for you)
- Extensive class library
- (ADO.NET, ASP.NET, DirectX, Web Service)
Java
C
C
C
4A new component model
- A component is a binary module that can be shared
- Important to developers because
- No need to release the source code to public
- Upgrade can be done by plug and play at binary
level
System
Component
5DLL (Dynamic Link Library) before .NET
- Evolution of DLL
- In C era, DLL is a library of shared functions
- In C era, DLL is a binary component known as
COM, which consists of a collection of objects - Problem
- Replacing an old COM with a new one is difficult
- The addresses of the functions are changed
- How to find the new addresses in the new COM
without re-link the entire system?
6The problem with binary component replacement
Old component 1234 foo()
Old System Exec foo(), jump to address 1234
7Where is foo()?
- Address of foo() is changed in new component
- How to solve this problem without relinking the
entire system
Old System Exec foo(), jump to address 1234
8COMs solution
- Use a QueryInterface() function to find the new
address
Old System Exec foo(), - Get IUnknown - Call
QueryInterface() - jump to new address
IUnknown
QueryInterface()
9COM way
- Lookup table approach
- Get the IUnknown pointer from a known address in
the new component - IUnknown points to a lookup table has a pointer
to a function called QueryInterface() - Use this function to find the new addresses of
the functions/objects - Tedious from the developer point of view
- A lot of extra coding
10DLL Hell
- Install a new software that uses a ver 2.0
component - The component is shared by many other software
- Windows supports only one version
- ver 1.0 COM is replaced by ver 2.0
- Other software are FORCED to use ver2.0 component
- But these program were only tested using ver1.0
- ver2.0 should be backward compatible with ver1.0
- Backward compatibility is difficult to do in
practice - Software may break
- The problem caused by replacing the old DLL with
new DLL is known as DLL hell
11.NET solution
- COM programming is complex, needs to manipulate
the IUnknown pointer we also have DLL hell - .NET
- CLR Common Language Run-time
- Virtual machine approach (like Javas JVM)
- Source code (C, VB, etc) are complied into byte
code called MSIL (Microsoft Intermediate
Language) - Byte code is mapped to executable code when it is
loaded to the machine - CLR converts byte code to executable code, and
fills in the actual physical addresses (linking
on-demand)
12.NET solution
- Pros
- The byte code is abstract, and can be run on any
platform - Because we are dealing with meta-code, CLR has
the full information to resolve unknown addresses - the COMs style of programming is obsolete
- Multiple versions, side-by-side execution
- .NET supports multiple versions, no more DLL hell
- Con
- Need to convert byte-code at loading time,
therefore slower response
13Overview of .NET
C
VB
C
Perl
Python
Cobol
Smalltalk
Class Library
ADO.NET GUI XML/SOAP
DirectX etc
14Advantages of .NET - simplification
- Language interoperability
- Can mix VB with C, or any combination !!
- Because all languages are compiled into the same
intermediate language (MSIL) code - Software distribution is simplified
- Resolving address references is done by CLR
- Support of multiple versions
- Hugh class libraries
- Code reuse
15- Common Language Runtime (CLR)
- Provides the environment to support multiple
languages, simplifies deployment and management - Loader, Just-in-time compiler, garbage
collection, security, debugger, type checker,
thread support, - Common Type System (CTS)
- Define the data types and programming constructs
supported by the CLR - Common Language Specification (CLS)
- A subset of CTS that all .NET languages must
agree upon, so as to support language integration
(e.g. mixing of VB and C)
16Similarity with Java
- Both environment are supported by virtual machine
- In Java the Java Virtual Machine (JVM)
- In .Net CLR
- Java Platform, Enterprise Edition (JEE)
- One language, multiple platforms
- .NET
- One platform, multiple languages
- Open source .NET platform
- Mono, DotGNU both runs on Linux
- C is an open standard (!!)
17JEE vs .NET vs LAMP
- JEE
- Pro system interoperability, can sells Java
applications to many different platforms - Con complex
- .NET
- Pro support multiple languages integration
- Con MS platform (unless Mono provides real
alternative) - LAMP (Linux/Apache/MySql/Perl/Python/PHP)
- Pro free
- Con open source, lack of support
18Compile and run simple C program
- using System
- class HelloWorld
-
- public static void Main()
-
- Console.WriteLine(Hello C world)
-
-
- Save Hello.cs
- Compile csc Hello.cs
- Run Hello
19Compiler options
- csc -?
- Shows you the list of output options
- csc /texe Hello.cs
- Output Hello.exe application, the default
- csc /tlibrary Hello.cs
- Output Hello.dll assembly (a library
component) - What is an assembly?
- The basic unit of a binary file in .NET,
containing byte code from several source files
20GUI version of Hello c world
- using System
- using System.Windows.Forms //using the GUI
library - class HelloWorld
-
- public static void Main()
-
- MessageBox.Show("Hello c world") //a GUI
box -
-
- Save as HelloBox.cs
- Compile csc HelloBox.cs
- Run HelloBox
- Display a box containing the message Hello c
world
21Compile from multiple source files
- HelloApp.cs
- using System
- class HelloWorld
-
- public static void Main()
-
- HelloMsg obj
- new HelloMsg()
- obj.Write()
-
-
- HelloMsg.cs
- using System
- using System.Windows.Forms
- public class HelloMsg
-
- public void Write()
-
- MessageBox.Show
- ("Hello c world")
-
-
Compile csc HelloApp.cs HelloMsg.csRun HelloA
pp
22To make HelloMsg.dll a sharable component
- csc /tlibrary HelloMsg.cs
- To link the component with the main program
HelloApp.cs - csc /rHelloMsg.dll HelloApp.cs
- Run HelloApp
23Deployment
- To distribute software under .NET is a huge
simplification compared to COM - Just copy the assembly files and distribute !
- To distribute a shared component securely is
slightly more complicated - Make the component a strong-name assembly
- Add it to Global Assembly Cache (GAC) using
- gacutil.exe /if HelloMsg.dll
- Strong-name assembly uses public key cryptography
to ensure authenticity (code is from the
originator) and integrity (code has not been
modified)
24Strong-Named Assembly
- Generate a public-private key pair
- sn k myKey.snk
- Add key info and version number to source file
- if STRONG
- assembly System.Reflection.AssemblyVersion(1.0.
0.0) - assembly System.Reflection.AssemblyKeyFile(myKe
y.snk) - endif
- Compile
- csc /defineSTRONG /tlibrary /outHelloMsg.dll
HelloMsg.cs
25Digital signature
- Public and private keys
- Encrypted (locked) data using public key,
decrypted (unlock) using private key, or vice
versa - Public key is known to the public, private key is
secret (only known to the developer) - The compiled file contains the digital signature
of the assembly - Digital signature
- Hashing the assembly into 128-bit fingerprint
- Then encrypt (sign) the fingerprint using private
key
26To protect the authenticity and integrity of the
assembly
- Download the assembly and its digital signature
- Hash the assembly
gt fingerprint A - Decrypt the signature using public key gt
fingerprint B - If A and B are the same, then
- The assembly is truly from, say, Microsoft
(authenticity) - Since the unlocked signature B is same as A,
therefore B must be locked by the private key of
the Microsoft - The assembly has not been modified by hacker in
the transmission (Integrity) - Otherwise A will be different from B
27 28Main()
- .exe must contains the Main() function
- Examples of Main()
- public static void Main()
- No input argument, no return value
- public static void Main(string args)
- Input arguments in a string array
- public static int Main(string args)
- Input in a string array, return an integer
29Class and object
- A class is the definition of a user-defined type
(UDT) - Defines the variables and the methods
- Does not take up memory
- An object is an instance (ie. a specific case) of
a class - Takes up memory
- The process of creating object is called
instantiation - Example
- int x
Type
Object
30Class and object
- int x int(10)
- //int x 10 also works
- Objects are created by a function known as the
constructor - Constructor int(10) has the same name as the
class - x is a reference (pointer) to the object
- Data (10) is localized and should be hidden
- Can only be accessed by the interface functions
x
10
INTERFACE
- / int()
31Class and object
- int is a system-defined type
- Object has
- Identity (the address of the object)
- objects have different identify even though their
content may be the same - Type (the interface functions)
- Value (the attributes)
- OO languages allow users to use the keyword class
to define their user-defined types
32Example
- public class Student
- private int ID
- private string name
- public Student(int ID, string name)
- this.ID ID
- this.name name
-
- public string getName()
- return name
-
-
attribute
constructor
method
33- The class has
- two attributes (ID and name)
- a constructor Student(int ID, string name)
- a method getName()
- private means the thingy can only be accessed
(seen) by methods within the class
(encapsulation) - Principle of encapsulation
- methods should be public, attributes should be
private - Since attributes are hidden, they can be changed
freely (loose coupling)
34Class and structure
- The syntax of class is quite similar to structure
in C that you have learned before - The only thing that is new is perhaps the set of
methods bundled inside the class - The idea is to allow manipulation of the
attribute (data) only by the set of methods
(interface) so as to achieve the purpose of
encapsulation (and therefore loose coupling,
abstraction, modularity)
35Constructor Student(int ID, string name)
- Create a Student object
- Student s new Student(7,James Bond)
- Constructor Student() has the same name as the
class - s is a reference (pointer) located in the stack
which points to the object located in the heap
Type
constructor
A reference to the object
36Default Constructor Student()
- Provided automatically by the system
- Convenient, you dont have to code the
constructor - Default constructor takes no argument
- Members are initialized to their default values
- 0 for numbers, null for string, false for bool
- Constructor does not specify the return type
- Because the return type MUST be Student,
therefore no need to specify
37Function overloading
- Overloading means different functions can have
the same name, as long as their signatures are
different - Signature parameter list return type
- e.g. constructors with same name but different
signatures - public Student()
- public Student(int ID, string name)
38To override the default constructor
- Write your own !
- public Student()
- ID -1 //default value
- name unknown //default value
-
39Forwarding construct (syntactic sugar)
- If you have too many similar overloaded
constructors, simplify them by the forwarding
construct - public Student(string name) this(0, name)
- public Student(int ID) this(ID,unknown)
- Call is forwarded to
- Student(int ID, string name)
- Syntactic sugar
- Does not add functionality, just sweeter to use
40Constructor
- Class is like a stamp that produces many objects
- Each object has its own set of attributes
- Two Student objects created by the constructor
- Student s1 new Student(7,James Bond)
- Student s2 new Student(8,Goldfinger)
s1
s2
8 Goldfinger
7 James Bond
41Object identity and this
- Object is uniquely identified by its address
stored in the reference pointer (e.g. s1, s2) - You need the reference pointer to uniquely
identify a function or an attribute - e.g. s1.name, s2.name, s2.getname()
- A special reference pointer this
- For an object to address to its own attributes or
functions, - e.g. this.name
42this
- Console.WriteLine(name0,s1.getName())
- s1.getName() invokes s1s function getName()
- The getName() in object s1 is called
- The reference s1 is passed implicitly as the
this pointer in getName() - public string getName()
- return this.name
-
- this can be omitted if there is no ambiguity
43Encapsulation
- Dont expose the details of an object to outside
world - Why? If this information is used by outside
world, you are less free to change the object in
future - Attributes (data) should not be exposed
(encapsulated) - private (the default)
- Can only be accessed by members in the object
- External world can only it via public methods
- Method
- private (the default),
- Set to public mode only if you want to expose it
44Visibility
- public
- accessible anywhere
- private
- accessible only by the class (not even subclass)
- protected
- accessible by the class and its subclass
- internal
- accessible only within an assembly
- protected internal
- accessibly within assembly or the subclass
- static
- Class level (global) visibility
45Example of visibility
- public class B
- public void MethodPublic()
- private void MethodPrivate()
- protected void MethodProtected()
- internal void MethodInternal()
- public class A
- public void foo()
- B b new B()
- b.MethodPublic()
- //OK
- b.MethodPrivate()
- //Not OK, private
- b.MethodProtected()
- //not OK, A is not a subclass of B
- b.MethodInternal()
- //OK if A and B are in
- the same assembly
-
46Type (class) visibility
- class also has visibility control
- public or internal
- Default is internal (if you dont specify
anything) - General rule
- If the visibility is not specified explicitly,
the default visibility is always the most
restricted one - Method -gt private
- class -gt internal
47Class level method (also known as static method)
- Object level method
- Need an object to invoke the method
- e.g. s1.getName()
- Class level method
- Invoke using the class name
- Convenient - the main reason of using static
method - Be careful !
- Not related to any object, cannot access any
object attributes - Console.WriteLine(hello)
- //WriteLine() is a static method in class Console
48Class level attribute (static attribute)
- Class level attribute
- Accessed directly using the class name
- Convenient, dont need an object reference
- Global data (convenient, but break encapsulation)
- e.g. Student.typename
- Static method can only use static attribute
- class Student
- static public string typename Student
- . . .
-
Cannot be accessed if private is used
49Class level and object levels method/data
- Class A
- public static void foo() //class level
- public static int x //class level
- public void bar() //object level method
- private int y //object level value
-
- A object1 new A()
- A object2 new A()
- A object3 new A()
50Class level and object levels method/data
Class level method/data Only one copy No need to
identify the object e.g. A.x, A.foo()
Class A int x foo()
object1
object2
object3
Object level method/data Many copies Need to
identify the object e.g. object1.bar()
int y bar()
int y bar()
int y bar()
51Property
- Data is usually private, retrieved only by public
method - e.g. read by getXXX() update by setXXX()
- Tedious, property provides a short-cut
- public class Student
- string name
- public string Name //property
- get return name //get method
- set name value //set method
-
- main()
- Student s new Student(7,James Bond)
- s.Name Goldfinger //update by set
- Console.WriteLine(name is 0,s.Name)
-
get
52C reference
- C/C pointer is error prone
- int a10
- int p //p is a pointer
- p a //p is the address of a
- p20 //deferencing, a20
- Pointer is powerful but is also a major source of
bugs - It can be used in two ways (address or value)
- p the address of the data
- p the value
53C reference
- Business applications almost always use pointer
to obtain value, not address - Only system programming needs to use pointer for
address manipulation - Reference (in C and Java)
- a pointer that only refers to the value
- Therefore can drop the
- i.e. an automatic deferencing pointer without the
- Less powerful, but also less bugs, good for
business applications - You can still refer to the address of a variable
in C by specifying the unsafe mode
54Memory allocation - stack and heap
- Memory for the variables are allocated either in
the stack or in the heap - In the stack
- Size of the variable is known at compilation time
- primitives char, int, double, structure,
pointer - In the heap
- Size of the type can be changed at run-time,
therefore it is not known at compilation time - e.g. array, objects created at run-time by
constructors
55Stack and heap
.exe file i (4 bytes) f (8
bytes) s(4 bytes) empty space Student
object
- void foo(int i)
- double f
- Student s new Student()
-
-
- Stack grows downward
- Heap grows upward
stack
Current stack pointer
heap
56Stack
.exe file static data i (4
bytes) f (8 bytes) s(4 bytes) i (4 bytes) f (8
bytes) s(4 bytes)
- Stack grows downward
- Supports recursion
void foo(int i) double f Student snew
Student() i-- if i!0 foo(i)
1st call
2nd call
Call foo() until i0
57Important - memory management in the stack
- Memory in the stack is freed automatically
- For local variables
- Whenever the variable is out of scope (function
returns to caller), stack pointer moves upward - Memory under the stack pointer is freed
automatically - For global variables (static)
- Memory is allocated at the top of the stack
- Freed automatically when the program is terminated
58Memory management in the heap
- Memory in the heap must be freed explicitly
- C/C
- Remember malloc()?
- User must free the memory using delete()
- Forgot to free the memory?
- memory leak, system will run out of memory
- C and Java
- Heaps memory is freed automatically by Garbage
Collector - Less chance for error
59Garbage collector algorithm
- How to free objects in the heap automatically?
- Object is addressed by a reference pointer in the
stack - Collect all reference pointers, find all objects
that are linked to the pointers (build an object
graph) - Objects that are not linked to any reference can
be deleted - When to carry out this garbage collection
process? - A slow process, only do it when the system runs
out of memory
60Object graph
Object in heap
Stack
A Student object
A String object
ID name
s1
James Bond
Goldfinger
ID name
Unconnected object will be deleted by the
garbage collector
61Parameter passing in C
- The default is to pass parameter by value
- Same as C
- public static void Main()
- int x10
- foo(x)
- Console.WriteLine(x0, x) //x10
-
- public static void foo(x)
- x20 //x in Main()is not affected
Pass by value
62Pass by value
- A copy of x is passed via the stack
- Pass by value is safe because the callers
program is not affected by calling an unknown
function
Stack
10
Mains x
10
Copy of x passed to foo()
63Pass reference by value is more subtle
- What if we pass a reference s to bar(s)?
- public static void Main()
- Student s new Student(7,James Bond))
- bar(s)
- Console.WriteLine(name0,s.getName())
-
- public static void bar(Student s1)
- s1.setName(GoldFinger)
name changed to GoldFinger!
64Pass reference by value
- A copy of the reference is passed by value via
the stack - Both references (s s1) point to the same object
! - Change s1 also changes s in Main
- The name in object s is changed by bar(s) to
Goldfiner
FF0000
s
FF0000
s1
James Bond
65Why this time bar() has no effect on the name of
s?
- public static void Main()
- Student s new Student(7,James Bond))
- bar(s)
- Console.WriteLine(name0,s.getName())
-
- public static void bar(Student s1)
- s1 new Student(8,Goldfinger)
This time name is still James Bond
s1 points to a new object
66Pass reference by value
- Initially a copy of the reference is passed by
value via the stack
FF0000
FF0000
James Bond
FF0000
67Pass reference by value
- public static void bar(Student s1)
- s1 new Student(8,Goldfinger)
-
- s1 in bar() points to a newly created object
FF0000
FF0000
James Bond
FF0010
FF0010
Goldfinger
68C parameter modifiers - in, out, ref, params
- in
- Parameter is passed by value, the default
- out
- For returning several values (return value can
only return a single entity) - out keyword must also be specified by the caller
- main()
- int x0 int a string str
- foo(x, out a, out str)
-
- public void foo(int x, out int a, out string s)
69ref
- Pass by reference, callers data is modified
- Like passing an address, but no need to
dereference using - main()
- int x10 int y20
- swap(ref x, ref y)
- Console.WriteLine(x0,y1,x,y)
-
- public static void swap(ref int x, ref int y)
- int temp
- tempx xy ytemp
-
70params
- To pass a varied number of parameters as a single
argument - e.g. like the printf() in C
- main()
- Student s1new Student(007,James Bond)
- Student s2new Student(008,Goldfinger)
- foo(s1, s2) //s1,s2 pass as params list
-
- public static void foo(params Student list)
- foreach (Student s in list)
- Console.WriteLine(name0,s.getName())
-
71Naming convention recommended by MSDN
- For public interfaces and properties
- mark all word boundaries in uppercase
- PascalCasing
- For private interfaces and parameters
- like PascalCasing, except first letter is in
lowercase - camelCasing
- Ref http//dotnet.di.unipi.it/EcmaSpec/PartitionV
/cont4.html
72Example
_xxx is an internal parameters
- public class Base
- private string _name
- public void SetName(string newName)
- _name newName
-
-
PascalCasing for public interface
camelCasing for parameters
73Some key concepts in OO
- Encapsulation
- Inheritance
- Polymorphism
- Delegation
74Key concepts in OO
- How to develop software quickly and cheaply
- Reuse code as much as possible
- But other peoples code takes time to learn
- To make our code easier for other to use, we must
- provide a simplified picture of our code
- Abstraction
- hide away the complexity
- Encapsulation
75Global data versus local data
- Code includes methods and data
- To reuse code, data must be readily available
- Non-OO languages, no restriction on the location
of data - Data can be any where
- OO languages, data is localized
- data is within the object, simplifies reuse
- Object has data, and the methods that operate
with the data
Data
Method
76Inheritance
- A problem with code reuse
- Would like to reuse a class, but
- some methods are not exactly what we want and
need to be modified - Need to add some more methods
- Solution
- Inherit the class (takes everything in the class)
- Override the methods we want to modify
- Add new methods
77Syntax of inheritance
- public class A
- private int a
- virtual public void foo()
-
- public B A
- virtual public void foo() //override
- virtual public void bar() //new method
-
- A is inherited by B, A is the superclass, B is
the subclass - Only virtual methods can be overrided
78Visibility
- Hide the state (private attributes) of an object,
exposes the interface (public methods) - class Base
- private int x0 //nobody can see x except class
itself -
- class Derived Base //inheritance
- public int GetX() return x //Not OK, cant
see x -
- A Deriveds object has memory for x because of
inheritance, but cant access it because it is
private
79Encapsulation
- protected
- keeping family secret
- nobody can see it except the class and its child
- class Base
- protected int x0
-
- class Derived Base
- public int GetX() return x //OK
-
80Interface and implementation inheritance
- To reuse an inherited method
- Implementation reuse
- Useful but miss the main purpose of inheritance
- The main purpose of inheritance is to reuse the
Interface - Interface inheritance is much more important than
implementation inheritance - USB is an interface
- MP3, memory stick, digital camera, etc, are
implementations that inherit the interface
81Key concepts in OO
- Interface is the key to abstraction
- Users can only see the interface, not the hidden
implementation, so that the implementation can be
changed freely (flexible software) - Different implementations can share the same
interface - One interface, many different implementations
- Polymorphism (a flexible style of programming)
- All the implementations are based on the
interface - Implementations inherit the Interface
82Key concepts in OO
- Delegation
- The decoder in the MP3 player are made by other
companies - Your MP3 player sends request to the decoder and
asks the decoder to do some work - This kind of implementation reuse is called
delegation
83Flexible software
- Requirements always change, your software must
also be able to change in future - The OPEN-CLOSED PRINCIPLE (Bertrand Meyer)
- Closed for modification
- Dont change existing code
- Open for extension
- Add new code to satisfy the new requirements
84Object delegation New code (Open for extension)
Your base system (old code) (CLOSED for
modification)
delegation
inheritance
Class inheritance New Code (Open for extension)
Class inheritance New code (Open for extension)
85Why existing code should not be changed
- Clients perspective
- Changes are RISKY, e.g. banks dont like changes
- If the old code works, dont change it
- Banks are still running 40 years old COBOL
programs - Developers perspective
- Changing other peoples code is also difficult
86Programming to an interface, not to an
implementation
- In hardware, USB represents all types of concrete
devices (disk, mp3 player, ) - In OO, use an interface class Account to
represent all types of concrete objects
(SavingAccount and CurrentAccount) - The rest of the system can only see the base
class Account, not the concrete classes - As long as the base class (interface) is not
changed, we can change the concrete class without
affecting the rest of the system
87Abstract programming
- Interface makes it easy to change the
implementation (useful for software upgrade) - It also supports an abstract style of programming
(polymorphism) - Example
- You have saving account, current account,
currency account, etc - To write an application for depositing money into
your accounts, how to do it flexibly?
88IS-A relationship
- Inheritance is used to model the IS-A
relationship - SavingAccount is-a specialized type of Account
- Account is-a generalized type of SavingAccount
- A bank application has objects from
- SavingAccount , CurrentAccount, . . .
- If SavingAccount and CurrentAccount have similar
behaviour, how to write a more flexible program?
89- class Account
- protected double balance0
- public virtual void Deposit(double money)
-
- class SavingAccount Account
- public override void Deposit(double money)
- balance balance money
-
-
- class CurrentAccount Account
- public override Deposit(double money)
- balance balance money
-
-
90OO in one line
- Account anAccount new SavingAccount()
-
91OO in one line
- Account anAccount new SavingAccount()
- anAccount.Deposit(100) //deposit 100
- What happens
- Create a concrete (real) object of type
SavingAccount - Cast the type of anAccount to Account
- Rest of the system sees an object of type
Account, not SavingAccount - Why this is good
- Can use the code for a newer version of
SavingAccount, or even apply it to CurrentAccount
92Upcasting
- Technically this is known as upcasting
- a SavingAccount object is casted (change type) to
an Account - upcasting because books usually draw the base
class on top - Upcasting is safe
- Downcasting is dangerous
- Not allowed unless explicitly say so
- SavingAccount anAccount
- (SavingAccount) new Account()
Account
SavingAccount
Explicit casting, should be avoided
93Why Upcasting is safe
- Safe to treat SavingAccount object as an Account
object, because SavingAccount supports all
methods in Account (due to inheritance) - Implicit upcasting is automatically allowed
- Downcasting is dangerous
- Account object is casted into a SavingAccount
- SavingAccount can have more methods than Account
- Call a method in SavingAccount, but the concrete
object Account may not have it ! - Downcasting must be explicitly coded, you must
know what you are doing
94Difference between class and type
- Class interface implementation
- Type interface
- This distinction is useful because it emphasizes
the importance of pure interface inheritance - Example
- Ant is a type of insect, bee is also a type of
insect - Insect is the base type
- abstract - a generalization of things that have 6
legs - Ant and bee are the subtypes
- concrete implementation
95Subtyping
- When to use inheritance
- To model the relation that B is-a subtype of A
- This means that
- B is similar to A
- B inherits all the interfaces of A
- What applies to A can also apply to B (but not
vice versa because B may have additional
interface) - We can treat B as if it is A
- Important, this leads to polymorphism
96Polymorphism
- Subtyping leads to a flexible style of
programming - Polymorphism
- SavingAccount, CurrentAccount,etc can be treated
uniformly as Account because they share the same
interface
97Polymorphism
- All subtypes of Account can be treated uniformly
- Main()
- Account accounts new Account2 //init
- accounts 0 new SavingAccount()
- accounts 1 new CurrentAccount()
- foreach (Account obj in accounts) //do some work
- obj.PrintName()
-
- Output
- SavingAccount
- CurrentAccount
98This example is what OO is about
- Subtypes SavingAccount and CurrentAccount are
both treated as Account (upcasting) - Programming on the abstract base class (Account),
not on the concrete subclass (SavingAccount,
CurrentAccount) - Adding a new subclass in future (e.g.
USDAccount), the rest of the code remains the
same (good flexible code)
99- Main()
- Account accounts new Account3 //init
- accounts 0 new SavingAccount()
- accounts 1 new CurrentAccount()
- accounts 2 new USDAccount()
- foreach (Account obj in accounts) //no change
- obj.PrintName()
-
- Output
- SavingAccount
- CurrentAccount
- USDAccount
100- Programming the interface, not the implementation
- Interface is more important than the
implementation - Easy to replace an implementation (your printer),
but not the interface (the printer port is more
than 30 years old) - Build your system around interfaces
(Account)
(SavingAccount)
101Pure implementation inheritance
- Inherit the implementation, not the interface
- (not particularly useful, just to illustrate the
concept) - public class A
- protected void Foo() . . .
-
- public class B A
- public void Bar()
-
- class A has no public interface
- class B inherits the implementation of Foo() in A
102Pure interface inheritance
- Inherit the implementation, not the interface
- Cs interface cannot have implementation
- Methods are public
- interface A //no implementation
- void Foo()
-
- public class B A
- public void Foo() //do something
- public void Bar()
-
103Abstract Class / method
- abstract class is a class that cannot be
instantiated - abstract public class Account ...
- abstract method has no implementation (also known
as pure virtual function) - Cannot instantiate a class that has an abstract
method, ie. it is like an abstract class - public class Account
- abstract public void Deposit()
-
- Account f new Account() //ERROR
- Account g new SavingAccount() //OK
104Difference between interface and abstract class /
method
- Abstract base class
- Cannot be instantiated, but can have
implementations - Interface
- Cannot be instantiated, has no implementation
- Clear intent use it purely for interface
inheritance - Good OO design interface-based programming
- Problem with class
- Mixed interface with implementation
105Static versus run-time binding
- public class Account
- public string GetName() //non-virtual
- public virtual void Deposit() //virtual
- public class SavingAccount Account
- public void Deposit()
- public class CurrentAccount Account
- public void Deposit()
- if () Account obj new SavingAccount()
- else Account obj new CurrentAccount()
- obj.GetName() //which method to call?
- obj.Deposit() //which method to call?
-
106- obj.GetName()
- Not a virtual function, the method to call is
known at compilation time - Static binding (bind at compilation time)
- Account.GetName() is called
- e.g. JMP 00ABCD //jump to the method
- obj.Deposit()
- obj is a pointer to different concrete xxxAccount
object - the method to call can only be known at run time
(because of polymorphism) - Run-time binding
107Run-time binding (or late binding)
- Binding
- The translation of name into physical address
- Run-time binding
- The translation is done at run-time
- also known as
- late binding
- dynamic binding
- Polymorphism depends on run-time binding
108How run-time binding (polymorphism) is implemented
- Each class has a vtable (virtual table)
- vtable contains addresses of the virtual function
- Every object has a vtable pointer (vptr) to the
vtable
Account
The Account vtable
an Account object
Account.Deposit()
vptr attributes
obj
The SavingAccont vtable
a SavingAccount object
Account
SavingAccount.Deposit()
vptr attributes
obj
109Dynamic binding under the hood
- Compile obj.Deposit() to ((obj-gtvptr0))(obj)
- obj is a pointer to the object
- obj-gtvptr is a pointer to vtable
- obj-gtvptr0 is the 1st slot in the vtable
- because Deposit() is the first virtual method
- (obj-gtvptr0) is the address of Deposit()
- ((obj-gtvptr0))(obj) passes obj as this
pointer - If obj is an Account, then Account.Deposit() is
called - If obj is a SavingAccount, then
SavingAccount.Deposit() is called
110More example
As vtable
As obj
- class A
- public void F0()
- public virtual void F1()
- public virtual void F2()
- private int a
-
- class B A
- public override void F1()
- public virtual void F3()
- protected int b
-
A.F1() A.F2()
vptr int a
Bs vtable
Bs obj
B.F1() A.F2() B.F3()
vptr int a int b
F0 is a non-virtual method F1() is overridden by
B, F2() has not been overridden, F3() is new
method in B,
111Why B can be treated as A (upcasting)
- The top part of B is same as A, so it can be
treated as A (upcasting, and hence polymorphism) - A obj new B()
Type A
This part of B is same as A
Bs vtable
Bs obj
B.F1() A.F2() B.F3()
obj
vptr int a int b
112Why B still contains int a?
- a is marked as private, cannot be accessed (or
used) by B - But B can still use A.F2() and the parents
method A.F1(), which can be invoked by calling
base.F1() - Both A.F1()and A.F2()can see and use a ,
therefore the object of B must provide the memory
for it
113One class, many objects, one vtable
- A obj1 new A()
- A obj2 new B()
- B obj3 new B()
As vtable
As object
A
obj1
vtpr
A.F1() A.F2()
Bs object
A
Bs vtable
obj2
vtpr
B.F1() A.F2() B.F3()
Bs object
B
obj3
vtpr
114Multiple inheritance
- Objects can belong to more than one type
- James is-a Student and a Photographer
- Useful to have multiple inheritance
- class StudentPhotographer Student, Photographer
- But it has problem with implementation ambiguity
- The diamond problem
115The diamond problem (due to the shape of the
diagram)
- Person s new StudentPhotographer()
- s.Hello() //Hello() has 2 implementations
- //which Hello() to call?
Person Hello()
Student Hello(Student)
Photographer Hello(Photographer)
StudentPhotographer
116Implementation and interface inheritance
- The diamond problem
- Multiple implementation inheritance
- Which implementation to use? Ambiguity
- Solution
- Single implementation inheritance, but supports
multiple interface - interface has no implementation
117Solution to the diamond problem
- StudentPhotographer inherits interface
IPhotographer - StudentPhotographer must implement the abstract
method Hello() - Only one implementation, no ambiguity
Person Hello()
interface IPhotographer abstract Hello()
Student Hello(Student)
StudentPhotographer
118- Interface IPhotographer
- void Hello() //visibility of hello()
decided - //by the concrete subclass
- class StudentPhotographer Student,
IPhotographer - public override void Hello()
- Console.WriteLine(StudentPhotographer)
- //or base.Hello() reuse Student.Hello()
-
-
119Interface can be inherited
- interface IA
- void Hello()
- interface IB IA
- void MoreHello()
-
- Multiple interfaces inheritance is OK
- interface IC IA, IB
- void YetMoreHello()
- Dont have the diamond problem since we dont
have the problem of multiple implementations
120Notation used by Microsoft
denotes interface
Object
Student
IPhotographer
StudentPhotographer
IAstronomer
StudentAstronomer
Class inheritance
Interface inheritance
121RTTI run time type identification
- Lets say we have an array of Student,
StudentPhotographer, and StudentAstronomer - How to find student that can take
IPhotographer.Photo()? - Student sa new Student,
- new StudentPhotographer(),
- new StudentAstronomer()
- foreach (Student s in sa) s.Photo()
- //Error class Student does not support Photo()
122RTTI run time type identification
- To select a specific type of object at run time
- as keyword
- foreach (Student s in sa)
- IPhotographer p s as IPhotographer
- if (p!null) p.Photo() //OK
-
- if s is-a IPhotographer, then p is a ref to the
object otherwise pnull
123C data type
- In C, everything are objects, and all objects
are derived from System.Object
System.Object
class
String
Array
. . .
ValueType
Reference type
Int32
Char
Double
Void
. . .
struct
124All objects are derived from System.Object
- Methods in System.Object are inherited by all
objects - Equals() compare object reference only, not the
state of the object - GetHashCode() default returns a hash code
(integer) of the reference to the object - GetType() return a type object
- ToString() e.g. ClassStudent.Student
- Finalize() use to remove object from heap
- MemberwiseClone() return a shallow copy of
object
125Syntax of inheritance
- The following constructs are the same
- // explicitly derived from System.Object
- class Student System.Object
- //same, object is an alias of System.Object
- class Student object
- //implicitly derived from System.Object
- class Student
126Reference-based semantics
- Methods in System.Object are based on reference
semantic - e.g. Equals() compares the references of two
objects - System.Object.Equals(object obj)
- Student s1 new Student(7,James Bond)
- Student s2 new Student(7,James Bond)
- bool flag s1.Equals(s2)
- Question
- Is flag true or false?
- What sort of parameters are we comparing to?
127- Answer flagFalse
- Reference semantic, compare references of s1 and
s2 - References of s1 (FF0000) and s2 (FF1000) are
different
FF0000
FF0000
s1
James Bond
s2
FF1000
FF1000
James Bond
128Problems with reference type semantic
- Some types, such as integer and string, are based
on value type semantic - compare the values, not the addresses
- Reference-type objects are expensive to maintain
- Reference-type objects must be stored in the
heap, cannot be removed cheaply (garbage
collector is slow) - Reference-type objects takes up more memory
- An integer takes up 4 bytes
- An object takes up at least 12 bytes
- 4 bytes for the object pointer, 4 bytes for the
value 4 bytes for the vtable pointer
129A compromise
- Value-type objects (e.g. char, integer, bool,
struct), override the reference-type semantic to
value-type semantic - Value types and reference types
- Value-based (int, double, bool, enum, struct)
- Allocate in stack
- Size of the variable is known at compilation time
- Reference-based (objects, array)
- Allocate in heap
- Size is not known at compilation time (size of
array can be changed dynamically)
130System data type
- char, int, and double are alias (shorthand) for
- char -gt System.Char
- int -gt System.Int32
- double -gt System.Double
- ValueType class is a subclass of System.Object
that overrides and changes the methods from
reference-based to value-based
131Conversion between reference type and value type
- Boxing - value type to reference type
- Wrap the value type by an object wrapper
- Put the object in heap
- Value to reference conversion is called boxing
- Like putting the value inside a box
- Unboxing - reference type to value type
- int i3 //value type
- Object o i //boxing - convert to reference
type - i (int) o //unboxing convert to value type
132Value-based semantics
- To change the comparison of the Student objects
from reference-based to value-based (in terms of
their ID) - Override the default method Equals()
- class Student
- public override bool Equals(object obj)
- if (this.ID obj.ID)
- return true
- else
- return false
-
-
ID is a property in this example
133GetHashCode()
- The default is to hash the objects reference
- Student s1 new Student(7,James Bond)
- Student s2 new Student(7,James Bond)
- bool flag
- (s1.GetHashCode()s2.GetHashCode())
- Question
- Is flag true or false?
- Answer
- false, in our example, s1FF0000, s2FF1000
134GetHashCode()
- To hash the object by value, override
GetHashCode() - class Student
- public override int GetHashCode()
- return ID.GetHashCode()
-
-
Invoke the built-in hashcode method in type int,
which is value-based
ID is of type int Value-base semantic
135struct
- struct is a value type (size known at compilation
time) - Main()
- Complex f new Complex()
- f.real 1.0
- f.imag 2.0
-
- struct Complex
- public double real //default is private
- public double imag
136Difference between struct and class
- Same syntax
- struct is value-type, memory allocated in the
stack at compilation time, cannot be changed at
run-time! - class is reference-type, only the reference
pointer to the object is allocated in the stack - If you have permanent data that do not want to
change, use struct - class is more flexible and is important in OO
because the reference can point to different
object at run-time (polymorphism)
137struct vs class (value vs reference type)
- struct Complex
- public double real
- public double imag
-
- Complex f1new Complex()
- Complex f2new Complex()
- f1.real10
- f1.imag20
- f2f1 //copy value
- f1.real 99
- //f2.real10, not changed
- class Complex
- public double real
- public double imag
-
- Complex g1new Complex()
- Complex g2new Complex()
- g1.real10
- g1.imag20
- g2g1 //copy ref!!
- g1.real 99
- //g2.real99, changed!!
138struct vs class (value vs reference type)
- struct
- f1f2, copy the value
- f1.real99, f2 is not changes
- class
- g2g1, copy the reference
- g1.real99, g2 is changed
f1.real f1.imag f2.real f2.imag
g1 g2
FF0000
FF0000
stack
stack
real imag
heap
139Shallow copy and deep copy
- Shallow copy
- g2g1, only copy the reference
- the default
- Deep copy
- make a new copy of the object
- Should implement the ICloneable interface
g1 g2
g1 g2
FF0000
FF0000
real imag
FF0000
FF1000
real imag
real imag
140Shallow copy
- Student s1 new Student(7,James)
- Student s2 s1 //shallow copy
- Only the address of s1 is copied to s2
- For deep copy, use Clone() in ICloneable
141Deep copy by implementing the ICloneable interface
- Student s1 new Student(7,James)
- Student s2 (Student) s1.Clone() //deep copy
- public interface ICloneable
- object C