Classes

Classes are another programming convention I will expect all of you to be quite familiar with. How to declare classes, how to define them, public/private/protected scopes, methods, attributes, inheritence, polymorphism, etc. We will be introducing some new implementation strategies to classes, which I'm going to focus on more on this page. Let's start with a bare-bones examples, that we'll then add to later on:

public class Slacker
{
protected int alpha;

public Slacker() { alpha = 42; }

public virtual void print()
{
Console.WriteLine("alpha = {0}", alpha);
}
}


Not terribly fancy. Your programming projects leading up to this class likely should have included many more methods, attributes, constructors, and destructors, but the example here can serve as a quick way to represent those larger projects.

One thing of important note in C# relates to inheritance. We cannot derive new classes from more than one single parent class here, but this does afford us one convenience: the use of base. base is the general way a derived class can refer to its parent class, which can be helpful in order to refer to method implementations from the parent class that we'll want to utilize within the child class as well. For example:

public class Slackest : Slacker // Slackest being derived from Slacker
{
public Slackest() : base() // Help initialize by calling the base class default constructor
{
omega = 1729;
}
public override void print()
{
base.print(); // This will print the value of "alpha"
Console.WriteLine("omega = {0}", omega);
}

private int omega;
}


The override keyword here is necessary as part of the re-implementation of the base classes' virtual method.



C# will introduce two new access modifiers, in addition to public, private, and protected: those are internal and protected internal. internal limits access to only code within the current assembly. protected internal limits access to code within the current assembly and derived classes in other assemblies. Some of the rules you have to follow when using access modifiers in C#:

  • Classes and structs declared in a namespace (as opposed to nested within another class), may be either public or internal.
  • Derived classes cannot be more accessible than their parent classes.
  • Members of both structs and classes are private by default.
  • namespaces, interface members, enumeration members, and user-defined operators are always public. namespaces may contain non-public members, though.



C# introduces the idea of a sealed class (example: sealed public class Example). Basically, these are classes that prohibit derivation. string is a sealed class.



There also exists the idea of a partial class, which is a... well, partial definition of a class. For example, I might find it useful to define my very complex, complicated classes in such a fashion:

// This part will be the basic, bare-bones definition to kick-start implementation
public class VerySmart
{
// declare/define constructors, print methods, properties, interfaces, etc.
}

// This will be where all of my AI development will take place
public partial class VerySmart
{
// declare/define all manner of machine learning mechanisms
}

// This will be where all of my scientific visualization code will be implemented
public partial class VerySmart
{
// declare/define my data crunchers, GUI's, options for visualization
}


This is an excellent "divide and conquer" approach to large scale projects, wherein multiple programmers can work on/implement the various features or components of a highly complex class, separately, without needing to actively pull down the most recent version published by their group members.



abstract is the keyword used to describe something as having an incomplete or missing implementation, that must be overriden. As opposed to virtual , which may forgo being overriden. In the context of methods, it would be what you might have referred to previously as pure virtual methods, which have no implementation themselves and exist only to provide a template for derived classes to then make implementations for. For example:

public abstract bool art();

You may also define classes themselves as being abstract. This will prevent you from ever instantiating an object from this class, but can be used to define an even broader template class by which other classes will be derived. An example of this might be concerning the representation of an organization of specialized people. You could build an abstract class called "Human", followed by derived classes called, "Customer", "Supervisor", and, "Tyrannical Overseer of Enrollment Undergraduate Advisor".



The modifier static can be applied to classes, attributes, methods, properties, operators, events, and constructors. Generally speaking, things that are qualified as static are not instantiated more than once, nor are they directly associated with instantiations. They simply exist, with your code referring to their singular definition directly. For example:

public class Slacker
{
public static readonly float PI = 3.14159;
// Other stuff
}


To refer to PI, you wouldn't access it like an attribute of an object you've declared, like alpha.PI but instead through the class itself: Slacker.PI.

public static class Wrapper may be the closest we get to standalone functions and code in C#, as you wouldn't create an object from this class in order to refer to its attributes and methods but instead would also use Wrapper.aGoodMethod(). Your utility or frequently used methods/definitions/variables might find a good home within a static class that is shared among the various projects you work on.