C# Classes and Inheritance CNS 3260 C#.NET Software Development
Scope What you can see where Different Types Namespace Class (static) Object (instance) Method Block
Namespace Access Modifiers internal (default) The type can only be accessed within the assembly public Anyone can access the type
Member Access Modifiers static Variable or Method belong to the class, not to an instance public Anyone can access protected Private to containing type and any derived types internal Public inside of the assembly (the.exe or.dll) no one else may access protected internal Public inside of the assembly or private to types derived from the containing class private (default) Access limited to the containing type
Fields: Initialization Fields can be initialized in three places Field declaration Constructor Method called by constructor public class MyClass { private int field1 = 5; private int field2; private int field3; public MyClass(int field2) { this.field2 = field2;} Uninitialized fields are zeroed out. (References are “nulled” out.)
Constructor Used to initialize members and set initial state Method has same name as class No return type Can be public, private, etc. Classes have a parameter-less default constructor unless another constructor is created (like C++ and Java)
Invoking a Constructor When using new to declare a class instance, memory is allocated, the variables are initialized, then the constructor is called no delete keyword, garbage collection handles memory management MyClass myClass = new MyClass()
Fields: const Resolved at compile time Better code security Can only be assigned in field declaration Implicitly static Can’t have static keyword! Can be assigned from a constant expression
fields: const example class MyClass { //private const MyClass myClass = new MyClass(); // Illegal private const MyClass myNull = null; // legal, but useless private const int CONSTINT1 = 5; private const int CONSTINT2 = 10; // resolved at compile time private const int CONSTINT3 = CONSTINT1 * CONSTINT2; public MyClass() { //CONSTINT1 = 6; // Illegal Console.WriteLine(CONSTINT3); }
fields: readonly Defines a read-only field that can be initialized at runtime Can’t be used for compile time expressions (i.e. switch statements, etc.) Can be set in the constructor and/or field declaration initialization When used on a reference type, you can access the object and change anything inside it, but you can’t assign the variable to a new reference.
class MyClass { private readonly MyClass myClass1 = new MyClass(); private readonly MyClass myClass2; private readonly int readOnlyInt = 5; public MyClass() { myClass2 = new MyClass(); readOnlyInt = 0; } public void Foo() { //readOnlyInt = 6; // Illegal //myClass = new MyClass(); // Illegal } fields: readonly example:
fields: static Represents a single entity for all instances of the type. Allows instances to share data. Can’t be accessed with an instance variable Can be accessed from within an instance method Created and initialized the first time the class is referenced in any way.
static fields example class MyClass { public static int myClassInt = 3; static void Main() { MyClass mc1 = new MyClass(); MyClass mc2 = new MyClass(); MyClass.myClassInt = 5; //mc1.myClassInt = 7; // Illegal (instance variable) mc1.ShowMyClassInt(); mc2.ShowMyClassInt(); myClassInt = 6; mc1.ShowMyClassInt(); mc2.ShowMyClassInt(); } public void ShowMyClassInt() { // Can access within instance member Console.WriteLine(myClassInt); }
The static Constructor Used to initialize static members Arrays Objects etc. Can’t have access modifiers Can’t be called explicitly Called after static field initializations
static Constructor example: using System.Text.RegularExpression; public class MyClass { private static Regex regex; static MyClass() { regex = new Regex(“[a-zA-Z]*”);}
static Methods Use the class name to access static methods If you are inside the class (in an instance or static method) then you don’t need the typename
class MyClass { public static void StaticMethod() { Console.WriteLine("StaticMehod()"); } public void CallStaticMethod() { StaticMethod(); // Legal } class MainClass { static void Main() { MyClass.StaticMethod(); // No instance variable MyClass mc = new MyClass() //mc.StaticMethod(); // Illegal mc.CallStaticMethod(); // Okay } static method example:
Destructors Listed as “Finalize()” in the MSDN Called by garbage collector You should not call the destructor non-deterministic threaded No access modifiers Must be parameter-less Implement IDisposable instead (learn about this later) if you need to dispose stuff deterministically (memory does not get returned until the GC does its job still.)
using System; class MyClass { ~MyClass() { Console.WriteLine("~MyClass()"); } class MainClass { static void Main() { new MyClass(); } Destructors
The this pointer Reference to the current instance readonly Not valid in a static context Used to explicitly reference fields in the object Used to call other constructors (like an initializer list)
this example: public class MyClass { private string data = “hello”; public MyClass() : this(“goodbye”) { } public MyClass(string data) { this.data = data; } }
Order of initialization Derived static fields Derived static constructor Derived instance fields Base static fields Base static constructor Base instance fields Base constructor Derived constructor (See OrderOfInitialization Demo)
Double initialization If you give a value-type member a default value, and then assign to it in the constructor, you waste time
Inheritance “Classes support single inheritance, and the type object is the ultimate base class for all classes.” - Standard (p. 40) One type of inheritance (public) public class Base : object { public void fun(){} } public class Derived : Base { public void fun(){} }
class Modifiers abstract - Cannot be instantiated sealed - Cannot be inherited from
Hiding Hide a method or field in the base class by declaring one with the same name in the derived class for methods, the entire signature must match, otherwise the base method is not hidden (unlike C++) You can access the hidden member by using the base keyword Causes warning if you don’t use the new keyword No such thing as virtual fields, only hidden fields (true in Java and C++ as well)
Warning To get rid of warning, use new keyword Tells the compiler you (think) you know what you are doing
virtual and override virtual methods can’t be private (wouldn’t make sense anyways) public class Base : object { public virtual void fun(){} } public class Derived : Base { public override void fun(){} }
Overriding If a base virtual function is protected, the override cannot be public (See VirtualDemo)
Upcasting You can upcast in the traditional C++ way: Or using the as operator: Base b = new Derived(); ((Derived)b).fun1(); Base b = new Derived(); (b as Derived).fun1(); Derived Base cast (See Upcasting Demo)
Casting Casting using the in the traditional way throws an exception if the runtime value cannot be cast to the requested type. Casting using the as operator returns null if the runtime value cannot be cast to the requested type. Neither style is faster if the cast is successful. as is faster if the cast fails because exception code is slow. but... you have to test your object to see if it’s null.
abstract A class can indicate that it is incomplete, and is intended only as a base class for other classes, by including the modifier abstract. Such a class is called an abstract class An abstract class can specify abstract members -- members that a non-abstract derived class must implement abstract classes cannot be instantiated. public abstract class MyAbstractClass { protected abstract void AbstractFun(); }
Abstract Classes can be abstract Not structs since they are sealed If they contain “at least one” (C++ idiom) abstract method, then the class must be declared as abstract Unlike C++, you can not write implementation for an abstract function You can however write implementations for non-abstract functions in abstract classes an abstract class cannot be sealed
Abstract Methods An abstract method is implicitly virtual it cannot have the virtual modifier An abstract method declaration is permitted to override a virtual method. This allows an abstract class to force re-implementation of the method in derived classes, and makes the original implementation of the method unavailable. public abstract override void F(); abstract methods must be protected or public
Sealed Sealed classes cannot be inherited from Structs (all valuetypes) are implicitly sealed Just put sealed in front of class name All Simple Types (including string) are sealed. public sealed class MySealedClass { }
base Refers to the immediate parent Can view all names visible from the immediate parent Can use base to call base constructors
Order of initialization OrderOfInitialization Demo Be aware of double initialization: a member has a default value, and then is set again in the constructor.