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
© Copyright 2026 Paperzz