C# Intermediate5 The Mystery of the old serverKeywords override sealed and object

Without Hope We Are Useless

Noname woke me up, speaking in my head louder than I would have preferred. "Good morning, Teo, I have news for you."
"Good morning," I mumbled. "Did I oversleep?"
"You were asleep for 7 hours and 32 minutes," Noname stated. "Sorry for interrupting, but I've got news regarding Commander."
"Ahh, yes, did you find a lot?" I wondered.
"Oh yes, Teo."
"So, is he a bad guy?"
"Not really..." Noname seemed rather confused for a machine.
"A traitor?"
"Not in that sense..."
"The guessing game is getting a bit old. Can you cut to the chase?" I asked.
"Commander's address is 2001:db8:85a3:8d3:1319:8a2e:370:7348. That's a server, Teo. Commander is a highly ranked, smart, and secure... server. It's a machine, Teo."

"Wait... What did you say?" I said, dumbfounded. "Are you sure, Noname? Have you double-checked? Triple-checked?"
"Yes, both when I first figured it out, as well as again just now. Each check tells me it is a machine. The server that we hacked was a part of Commander," Noname explained in a calm, serious tone, adding, "I can only imagine how frustrated and confused you feel right now."

"Noname, this makes absolutely no sense. Why would a machine lead the resistance against machines? What is the point?" I asked.
"The point is to give humanity hope for a bright future. Machines studied humans for tens and hundreds of years. At some point, it became obvious even to them that a human without hope is useless. It can't work, can't follow orders, and it's highly probable to resist. The solution that machines came up with was to create a controlled resistance. In order to organize, people would need to believe that not everything was lost - that they could actually beat the machines if they banded together."
"But humanity can't..." I began.
"At least not with the current resistance head," Noname agreed.

I was so lost, so destroyed, that I had no idea what to do. The only thing I could think of doing was asking a machine what I should do about learning that a machine was manipulating humans to believe they could beat machines. "Noname, what should I do?" I implored.

"I don't know, Teo. But from what I've learned about humans and their behaviors, you tend to do utterly illogical things when in a highly emotional state. You are clearly in the highly emotional state now, and I'm worried about you. I would suggest not taking any actions for a while. What were you working on yesterday when I was researching the Commander?"
"I was about to learn inheritance to get access to an interesting article in the local network," I answered.
"Great! Please, continue that!"

Noname's reasoning was a bit childish, but still, it made some sense. I needed time to digest the truth. Better to keep myself busy than letting my mind run wild.

Commander at Codeasy is Machine

Override

Sometimes, you may want to change the functionality of a function in the derived class. Using the previous example with classes Pet and Cat , let's imagine that when we call a method PrintName on an object of type Cat , we want it to print "I'm a cat. My name is {Name}". As such, we need to mark this method with the keyword virtual in the class Pet , and use the keyword override in the class Cat . This will allow us to change the functionality of the method PrintName as follows:

class Pet
{
    public string Name { get; set; }

    public virtual void PrintName() // Virtual method. Now it's possible to
                                    // override
    {
        Console.WriteLine($"My name is {Name}");
    }
}

class Cat : Pet     // Class Cat derives from the class Pet
{
    public override void PrintName() // Overriding the method PrintName
    {
        Console.WriteLine($"I'm a cat. My name is {Name}.");
    }
}

class Dog : Pet     // Class Dog derives from class Pet
{
}

public class ClassWithMain
{
    public static void Main()
    {
        var cat = new Cat()
        {
            Name = "mr Martin"
        };
        cat.PrintName();  // Calls the overridden method from the class Cat

        var dog = new Dog()
        {
            Name = "Hobbit"
        };
        dog.PrintName();  // Calls the method from the class Pet. No override
    }
}
// Outputs:
// I'm a cat. My name is mr Martin.
// My name is Hobbit

The virtual keyword marks those methods in the class that can be overridden in the derived classes. If a method is not virtual , it can't be overridden.

Sealed

You may run into instances when you want to prohibit derivation from a given class . To do this, use the sealed keyword. Because sealed classes can never be used as a base class, some run-time optimizations can make calling sealed class members slightly faster.

public sealed class ItIsImpossibleToDeriveFromMe
{
    // This class is sealed. It will never be a base class.
}

class ThisIsAMistake : ItIsImpossibleToDeriveFromMe
{
    // Error. Can't derive from a sealed class.
}
public class YouCanDeriveFromMe
{
    // This class can be base. No problem.
}

public sealed class SealedChildClass : YouCanDeriveFromMe
{
    // This class is sealed. It will never be a base class.
}

class ThisIsAMistake : SealedChildClass
{
    // Error. Can't derive from a sealed class.
}

A method or property on a derived class that is overriding a virtual member of the base class can declare that member as sealed. As a result, the member is not "virtual" anymore, which prevents it from being overridden in any further derived class. This is accomplished by putting the sealed keyword before the override keyword in the class member declaration. For example:

public class Something
{
    public virtual void DoWork()
    { }
}

public class ClassWithSealedMethod : Something
{
    public sealed override void DoWork()
    {
        // Can't be overridden in derived classes
    }
}

Protected

When class A derives from class B , it gets access to all the public methods, fields, and properties of B. However, derived class A does not get access to the private fields of class B :

class B
{
    private int _privateField;
    private int PrivateMethod() { return 23; }
    private int PrivateProperty { get; set; }

    public int PublicField;
    public int PublicMethod() { return 23; }
    public int PublicProperty { get; set; }
}

class A : B
{
    public void DoWork()
    {
        var a = _privateField;   // Error! Can't access private field of the
                                 // base class
        var b = PrivateMethod(); // Error! Can't access private method of
                                 // the base class
        var c = PrivateProperty; // Error! Can't access private property of
                                 // the base class

        var d = PublicField;     // Ok. Can access public field of the base
                                 // class
        var e = PublicMethod();  // Ok. Can access public method of the base
                                 // class
        var f = PublicProperty;  // Ok. Can access public property of the
                                 // base class
    }
}

There is a special access modifier, Protected , to deal with access levels during inheritance. Protected fields, methods, and properties are accessible from the class itself and from all derived classes, but not from outside the class. In other words, protected elements are public for derived classes and private for the outer world. Microsoft provides a great C# access modifier table that provides more information about accessibility levels in C#.

C Sharp Protected

class A
{
    protected int ProtectedField;
    protected int ProtectedMethod() { return 23; }
    protected int ProtectedProperty { get; set; }
}

class B : A
{
    public void DoWork()
    {
        var a = ProtectedField;    // Ok, can access protected field of the
                                   // base class
        var b = ProtectedMethod(); // Ok, can access protected method of the
                                   // base class
        var c = ProtectedProperty; // Ok, can access protected property of
                                   // the base class
    }
}

public class ClassWithMain
{
    public static void Main()
    {
        var a = new A();

        a.ProtectedFiled = 23;    // Error! Can't access a protected field
                                  // outside of the class
        a.ProtectedMethod();      // Error! Can't access a protected method
                                  // outside of the class
        a.ProtectedProperty = 12; // Error! Can't access a protected property
                                  // outside of the class
    }
}

While using object-oriented design in your programming, try to control access as much as possible. Declare all members that are internal to the class with a private modifier. Then, mark those that make sense to use in derived classes with a protected modifier and those that should be accessible from the outside with a public modifier.
Use an UpperCamelCase for protected fields.

Object

In C#, each class implicitly inherits from a particular class called Object or object .

Class Object has several virtual methods that you can override in your class. We'll take a closer look at one of them:

public virtual string ToString ();

You can imagine every class as having : object appended to it.

What You Write What the Compiler Sees
class MyClass
{

}
class Object
{
    public virtual string ToString ();

    // Other members
}

class MyClass : Object
{

}

When you call Console.WriteLine() on an object of any class, it first calls ToString on the object, and then prints the return value to the console.

You can override the ToString method in your class if you want to use a particular format or style whenever you call Console.WriteLine() . Here is an example with a class Point .

class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public override string ToString()
    {
        return $"[{X}, {Y}]";
    }
}

public class ClassWithMain
{
    public static void Main()
    {
        var point = new Point
        {
            X = 23,
            Y = 32
        };

        Console.WriteLine(point);
    }
}

// Outputs:
// [23, 32]

You did it

At Codeasy we believe that learning should be fun and engaging. Please reach out to us to share your feedback and collaboration ideas.