Windows Programming Using C

Windows
Programming Using
C#
Classes & Interfaces
Contents
Classes
 Inheritance
 Operator Overloading
 Structs
 Interfaces

2
C# Classes


The class is the main data structure in C#
It blends ideas from both C++ and Java
 All
methods are declared inline, as in Java
 No C++ style header files
 Supports only single inheritance
 Inheritance syntax from C++
 Allows multiple classes to be declared in one file like
C++
 Methods can be used before being declared
3
Class Declaration
[attributes][access-modifiers]class ident
[:base-class]
{class-body}
 Attributes
& modifiers discussed later
 For now, just use public
 An optional base class can be used for
inheritance
4
Class Declaration
using System;
public class Person {
string name;
int age;
public Person(string nm, int ag) {
name = name;
age = ag;
}
public string getName() {
return name;
}
}
5
Access Modifiers
Modifier
Explanation
public
Visible to any method of any class
private
Visible only to methods of the declaring class. This is the
default access modifier if none is specified.
protected
Visible to declaring class and subclasses
internal
Visible to any method in the same assembly as the
declaring class
protected
internal
Visible to declaring class, subclasses, and classes in the
same assembly
6
Object Creation


Primitive types like int, char, etc. are value types
and are created on the stack
Objects are reference types and are created on
the heap
 Declare
an object reference variable
 Use the new operator to create a class instance on
the heap
 Assign this new instance to the reference variable
7
Object Creation

Person p = new Person(“Ann”, 34);
 This
creates a new instance on the heap
 The constructor for the new instance is invoked
 The reference to the new instance is assigned to the
variable
 The object will be destroyed when there are no more
references to it and it is reclaimed by the garbage
collector
8
Constructors
A constructor is a special method with the
same name as the class
 It is run to initialize the class
 Before it is run the class is
undifferrentiated memory
 After it is run, the memory is an instance of
the class

9
Constructors
Constructors never have a return type
 Constructors are usually public
 Constructors may be overloaded
 If no constructor is provided, the CLR will
create one which does nothing
 If any constructor is provided, no default
constructor will be created

10
Member Variable Initialization

C# allows you to initialize a member
variable when it is declared
 int
day = 30;
 This is called an initializer
If you do not provide an initializer, a default
value is assigned
 This means that there are no uninitialized
variables in C#

11
Default Values for Primitives
Type
Default Value
numeric
0
bool
false
char
‘\0’
enum
0
reference
null
12
Copy Constructors

A copy constructor is simply a constructor which


accepts an instance of the same class as a parameter and
makes a copy of it
You must create a copy constructor if you need one, the
compiler will not create one for you
public Person(Person p) {
name = p.name;
age = p.age;
}

13
This

this is a keyword referencing the current object

It can be used in any non-static class
It can be used to

 Disambiguate parameters
public Person(string name) {
this.name = name;
}
 Pass a reference to
List.add(this);
the current object
14
Static Members

Classes have two types of members
 Instance

Every class instance has its own copy
 Static



members
members
The member is associated with the class, not the instance
All instances access the same members stored with the class
Must be qualified with the class name, NOT the name of an
instance
15
Static Methods
Static methods are not associated with an
instance and have no this reference
 Static methods cannot refer to non-static
members
 Static methods are useful for

 Utility
operations associated with the class
 Operations which modify the static data of a
class
16
Static Constructors
Are invoked to initialize static members
 Are invoked before any other constructors
 A static constructor cannot have an access
modifier (ie. public)


A static constructor cannot access any
non-static members
17
Destructors
C# has a garbage collector
 When there are no more references to an
object, it is marked for destruction
 Some time later, the garbage collector will
actually destroy the object
 Unlike in Java, the object is guaranteed to
be destroyed

18
Destructors

A C# destructor looks like a C++ destructor


~MyClass() { /* do destructor work here */ }
That is the end of the similarities
 You
only need a destructor if you have to free
unmanaged resources like file handles
 References to managed objects will be handled by
the garbage collector without the need for a
destructor
 Never call a destructor directly, the garbage collector
will call it for you
19
Finalize


This syntax is really a shortcut for calling a
Finalize() method which will chain up to the
base class
It is translated to
~MyClass() {
try {
// work of destructor
} finally {
base.Finalize();
}
}
20
Dispose



The problem with destructors is that they will not
run until the object is reclaimed by the garbage
collector
This means that precious resources might be
held for longer than necessary
You can fix this by
 Implementing the IDisposable interface
 Defining the required Dispose() method
 Having clients call Dispose() when they have
finished with a class instance
21
Dispose
If Dispose() is called and freed the
resources, you must not have the
destructor do the same thing
 You can suppress finialization by

 GC.SuppressFinalize(this)

You should ensure that the resources are
only freed once
22
Dispose
using System;
class Testing : IDisposable {
bool is_disposed = false;
protected virtual void Dispose() {
if (!is_disposed) {
// only dispose once!
// perform cleanup for this object
GC.SuppressFinalize(this);
}
this.is_disposed = true;
}
~Testing( ) {
Dispose(false);
}
}
23
The Using Statement

Since there is no way to guarantee that
client code will call Dispose() , the
using statement is provided
using ( Font theFont = new Font( "Arial", 10.0f ) )
{
// use theFont
} // compiler will call Dispose on theFont

This guarantees Dispose() is called on
theFont when the using block is exited
24
Parameter Passing

Normally, value parameters (int, char, etc.)
are passed by value
 A copy
is made and passed to the method
 The method might modify the copy
 The copy is not returned and the original is
left unchanged

We can modify this using the ref keyword
to use pass by reference
25
Pass By Reference
public add3(ref int n) {
n = n + 3;
}
 Since a reference is used, the original
value in the calling code is modified
 There is no need to dereference anything
as you would do with a C pointer
26
Out Parameters



Definite assignment requires that a parameter
be initialized before it can be used
This means we have to initialize a variable
before we pass it to a method, even though the
method will set the value and never use it
We can use the out keyword to modify this
behaviour
27
Out Parameters
public void init(out int n) {
n = 34;
}
 This code can be passed an uninitialized
parameter
 It can assign a value to the parameter and
return it
28
Properties




Properties allow code to access the state of an
object as if they were accessing a field directly
However, a property does not access a field
A special class method provides the access and
controls what is determined
This simplifies the interface while prohibiting
unrestricted access to class internals
29
Properties

Access to properties is provided accessors
 A get
accessor to return the value
 A set accessor to set the value
These accessors are placed inside the
property declaration
 You can omit either the set or get accessor
if they are not needed

30
Properties

Consider adding a Name property
public class Person {
string name;
int age;
public Person(string nm, int ag) {… }
public string Name {
get {
return name;
}
set {
name = value;
}
}
}
31
Properties
The set accessor has no parameter
 The value passed to it is called value
 We can use the accessors like this:

Person p = new Person(“Jane”, 29);
Console.WriteLine(p.Name);
p.Name = “Janie”;
32
Readonly Fields

Readonly fields can only be assigned
 By
initialization or
 By a constructor
Sometimes, you want to create a public
static constant but cannot initialize it
 You can make it readonly so that it can be
initialized by one of the constructors

33
Readonly Fields
public class Color {
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}


We cannot initialize Black & White as constants because their
values cannot be computed at compile time
Making them readonly has a similar effect to making them constants
34
Contents
Classes
 Inheritance
 Operator Overloading
 Structs
 Interfaces

35
Inheritance
C# supports single inheritance
 Syntax:

 public
class ListBox: Window
Inherits all base class members
 It can extend the base class by adding new
members
 It can override any method in the base class with a
new method using the keyword new

36
Inheritance
public class EmployedPerson: Person {
float salary;
…
public float Salary {
get {return salary;}
}
}
37
Base Class Construction
The base class must be constructed
before the derived class
 To do this, each constructor for the derived
class must invoke the constructor for the
base class
 Constructors cannot be inherited, so each
class must implement its own

38
Base Class Construction
If the base class has a default constructor
which is accessible, it will be called
automatically
 If no default constructor is in the base
class, another constructor must be called
 A base class constructor is invoked with
the base keyword

39
Base Class Construction
public class EmployedPerson: Person {
float salary;
…
public EmployedPerson(string name,
int age, float salary):
base(name, age) {
this.salary = salary;
}
}
40
New Methods

When a derived class declares a method
with the same name as a method in the
base class it can
 Hide
the method in the base class
 Polymorphically override the method in the
base class

To hide the method in the base class, you
must use the new keyword
41
New Methods

When you invoke a new method in the derived
class
 A reference
to the derived type invokes the method in
the derived class
 If the derived instance is assigned to a base class
reference variable, invoking the method with the base
reference will invoke the base version of the method
 * see Person example
42
New Methods
public class PersonBase {
…
public string ClassName() {
return "PersonBase";
}
}
public class EmployedPerson:
PersonBase {
…
public new string ClassName() {
return “EmployedPerson";
}
}
…
PersonBase pb1, pb2;
EmployedPerson ep1;
pb1 = new PersonBase("Julie", 34);
ep1 = new EmployedPerson("Betty", 28,
37000.0);
pb2 = ep1;
Console.WriteLine("pb1.ClassName() =
{0}", pb1.ClassName());
Console.WriteLine("pb2.ClassName() =
{0}", pb2.ClassName());
Console.WriteLine("ep1.ClassName() =
{0}", ep1.ClassName());
PersonBase
PersonBase
EmployedPerson
43
Polymorphism
With true polymorphism, we can override
methods and the compiler will always
invoke the correct method
 For this to work

 The
method in the base class must be
virtual
 The method in the derived class must be
declared override
44
Polymorphism



System.Object declares the method ToString() as
virtual
This is provided to convert every object to a string
representation
We can override it in PersonBase by
public override string ToString()
{
return name + ", " + age;
}
45
Calling Base Class Methods


We want to override it again in the EmployedPerson
class
This time, we want to call the version in the parent class
using the base keyword
public override string ToString()
{
return base.ToString() + ", " + salary;
}
46
Versioning

Suppose we have classes
 BaseClass
 DerivedClass

Now, let’s add a virtual method to DerivedClass
public class DerivedClass: BaseClass {
public virtual void NewMethod() {…}
}
47
Versioning


All is well
Now, pretend the author of BaseClass decides
to provide the same method
public class BaseClass {
public virtual void NewMethod() {…}
}
 When this is compiled, a warning states that
NewMethod() in DerivedClass hides the one in
BaseClass
48
Versioning

The way this works is
 To
find a virtual method the compiler searches up the
class chain for the first method marked virtual
 For the derived class, this would be its version of the
method
 For the base class, its version would be used

The benefit of this is
 A base
class can be modified without breaking
anything done in a derived class
49
Versioning

The warning states
 Declare
it new to hide the base method and
eliminate the warning
 Declare it override to override the base
method
 Or leave as is to hide with a new virtual
method and still get the warning
50
Abstract Classes

A class can be declared abstract and not have a
body
 abstract

Any class with an abstract method must be
declared abstract
 abstract


public void MyMethod();
public class MyClass { …}
Abstract classes cannot be instantiated
Abstract methods must have implementations
before a class becomes concrete
51
Sealed Classes
A sealed class cannot be extended
 This is the same as final in Java
 To use it, place the sealed keyword
before the class declaration

52
System.Object
This is the root of all objects
 All classes are derived from it even if they
do not derive from any class
 This class provides methods which are
inherited by every object

53
Object Methods
Method
Purpose
Equals()
Compares two objects for equality
GetHashCode()
Provides a hash code
GetType()
Returns a type object for the object
ToString()
Produces a string representation
Finalize()
Cleans up non-memory resources
MemberwiseClone() Creates copies. Do not override!
ReferenceEquals()
True if two references refer to the same object
54
Boxing


Boxing is the conversion of one of the primitive types to
an object
Any of the primitive types can be




Assigned to an object reference
Passed to a method expecting an object as a parameter
In these cases, the compiler will automatically convert
the primitive into an object
int i = 57;
Console.WriteLine(“i={0}”, i);
This expects an object, boxes the primitive and then
calls ToString() on the resulting object
55
Unboxing


This is retrieving the primitive value from a
boxed value
It requires an explicit conversion since the type
stored in the object is unknown to the compiler
int i = 57, j;
Object o = i;
j = (int) o;
56
Nested Classes
One class can be nested within another
 This is often done for helper classes
unused outside the outer class
 Nested classes have access to all
members of the outer class
 Can be declared public if they can be used
outside the class

57
Contents
Classes
 Inheritance
 Operator Overloading
 Structs
 Interfaces

58
Operator Overloading





C# provides operator overloading similar to C++
All operators must be static, unlike in C++
The goal is to make user-defined classes more
like system types
Not all .NET languages support operator
overloading and equivalent methods should be
used if interoperability is an issue
* see example Fraction
59
Operator Overloading
To overload ==, you should also overload Equals
public override bool Equals(object obj) {
bool result = false;
if (obj is Fraction) {
Fraction f = (Fraction)obj;
result = numerator == f.Numerator &&
denominator == f.Denominator;
}
return result;
}

60
Operator Overloading
public static bool operator==(Fraction obj1,
Fraction obj2)
{
return obj1.Equals(obj2);
}
61
Pairing

Many operators must be overloaded in
pairs
 Overload
== and you must overload !=
 Overload < and you must overload >
 Overload == and you must overload
getHashCode()
62
Conversion Operators

Conversions can be
 Implicit
Automatically performed by compiler
 No loss of information

 Explicit
Requires cast by user
 Might involve loss of information

63
Conversion Operators
public static implicit operator Fraction(int i)
{
return new Fraction(i, 1);
}
public static explicit operator int(Fraction f)
{
return f.numerator / f.denominator;
}
64
Contents
Classes
 Inheritance
 Operator Overloading
 Structs
 Interfaces

65
Structs



Structs are lightweight substitutes for classes
Structs are always value type, not reference
types
Structs support
 Constructors
 Properties
 Methods
 Operators
 Indexers
 Nested
types
66
Structs

Structs do not support
 Inheritance
 Destructors
 Being
a reference type
You cannot extend a struct although it can
implement multiple interfaces
 All structs are derived from object

67
Structs
Structs are simpler than classes and
usually more efficient
 They can also be used to interface with
libraries written in C++

68
Declaring Structs
public struct Location {
private int xVal;
private int yVal;
public Location( int xCoordinate, int yCoordinate ) {
xVal = xCoordinate;
yVal = yCoordinate;
}
public int x {
get { return xVal; }
set { xVal = value; }
}
public int y {
get { return yVal; }
set { yVal = value; }
}
public override string ToString( ) {
return ( String.Format( "{0}, {1}", xVal, yVal ) );
}
}
69
Creating Structs

You can create a struct by
 Location
l1 = new Location(1,2);
 Location l1;
These both create the Location on the
stack as a value type
 The second one does not invoke a
constructor and field values must be
assigned before it can be used

70
Passing Structs
Since structs are value types, they will be
passed by value
 This means that changes made to a struct
in a method will not be passed back
unless a ref parameter is used

71
Contents
Classes
 Inheritance
 Operator Overloading
 Structs
 Interfaces

72
Interfaces

An interface is a contract which states
 All
implementers of the interface guarantee to
implement all
Methods
 Properties
 Events
 And indexers

 Of
the interface
73
Declaring Interfaces
[attributes][access-modifier]
interface ident
[:base-list] {interface-body}
interface IStorable {
void Read();
void Write();
}
74
Implementing Interfaces

A class can implement an interface


Using the same syntax as inheritance
Implementing the required methods, etc.
public class Document: IStorable
{
public void Read(){…}
public void Write(object obj){…}
…
}
 A class can implement multiple interfaces
75
Extending Interfaces
You can extend an interface using the
colon notation
 This allows you to add new requirements
to an existing interface
 You can extend several interfaces to form
the union of all their requirements in a new
interface

76
Working with Interfaces

Any class which implements an interface
can be assigned to the interface type
Document doc = new Document(“test”);
IStorable stor = (IStorable) doc;

Only the methods etc. defined in the
IStorable interface can be used on the stor
object
77
The is Operator
Before you cast an object to an interface, it
is good to know if the object implements
the interface
 The is operator can tell you this

If( doc is IStorable) {
stor = (IStorable) doc;
}

This avoids exceptions being thrown
78
The as Operator

The as operator
 Checks
to see if an object implements an interface
 If it does it casts it
 If it does not, it returns null
stor = doc as IStorable;
If(stor != null) {
stor.Read();
}
79
Explicit Interface Implementation



What happens if a class implements two
interfaces which require the same method?
The class must explicitly qualify the method
names with the interface names so that the
compiler can tell them apart
One can be left unqualified since it must belong
to the interface which has yet to have the
method implemented
80
Explicit Interface Implementation

A qualified interface name cannot
 Have an access modifier, they are all
 Be abstract, virtual, override or new

public
For example
 IStorable has a Read() method
 ITalk has a Read() method

The a class implementing both interfaces would
declare
 void
 void
Read()
ITalk,Read()
81