C#. Access to class members from instances of classes that make up the hierarchy. Features of using the reference to the base class.

Access to class members from instances of classes that make up the hierarchy. Features of using the reference to the base class. Keywords as, is. Ways to call methods with the same name in inheritance hierarchies. Static polymorphism

This topic explores the following:

  • instance access to class members that form a hierarchy;
  • access by reference to the base class to the elements of classes that form a hierarchy;
  • study of the features of the use of keywords is, as;
  • ways to call methods that have the same name in the class hierarchy.

Contents


Search other websites:

1. Using instances of classes that make up a hierarchy. Features of access to elements of a base class from an instance of an inherited class

If classes form an inheritance hierarchy, then you can declare objects (instances) of any of the hierarchy classes (except abstract classes and interfaces).

If instances of different classes are declared, then using these instances you can access the public elements of these classes. If some class is inherited from another class, then an instance of this class can be accessed:

  • to all public elements of this class;
  • to those public elements of the base class whose names are not “hidden” (overlapped) by elements of the derived class.
    From an instance of a class, you cannot access the elements of classes inherited from this one.

Figure 1 shows access from instances objA, objB, objC of classes A, B, C that form the inheritance hierarchy. An attempt is made from any instance to call the class methods of this instance and the methods of other hierarchy classes.

C#. Inheritance. Access to class elements from instances of these classes

Figure 1. Access to class elements from instances of these classes

 

2. An example that demonstrates access from instances of classes that make up a hierarchy

Below is the text of a demo program corresponding to Figure 1. The program was created using the Console Application template.

using System;
using static System.Console;

namespace C_sharp
{
  // Class A - base class
  class A
  {
    public void Show()
    {
      WriteLine("Method A.Show()");
    }

    public void ShowA()
    {
      WriteLine("Method A.ShowA()");
    }
  }

  // Class B - inherited class
  class B : A
  {
    public new void Show()
    {
      WriteLine("Method B.Show()");
    }

    public void ShowB()
    {
      WriteLine("Method B.ShowB()");
    }
  }

  // Class C - inherited from class B
  class C : B
  {
    public new void Show()
    {
      WriteLine("Method C.Show()");
    }

    public void ShowC()
    {
      WriteLine("Method C.ShowC()");
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // 1. Instances (objects) of classes A, B, C
      A objA = new A();
      B objB = new B();
      C objC = new C();

      // 2. Access to items using objA
      objA.Show(); // A.Show() is called
      objA.ShowA(); // A.ShowA()
      // objA.ShowB(); - error, no access: base class cannot expand to derived class
      // objA.showC(); - error, also no access

      WriteLine("-------------------");

      // 3. Access to items from objB object of class B
      objB.Show(); // B.Show() is called by default because
      // the B.Show() method “hides” (overrides) the  A.Show() method
      objB.ShowA(); // calling the base class method A.ShowA()
      objB.ShowB(); // B.ShowB()
      // objB.ShowC(); - error, access denied: base class
      // cannot extend to derived class capabilities

      WriteLine("-------------------");

      // 4. Access to items from objC object of class C
      objC.Show(); // C.Show() - this method overrides the base class methods
      objC.ShowA(); // A.ShowA()
      objC.ShowB(); // B.ShowB()
      objC.ShowC(); // C.ShowC()
    }
  }
}

The program result

Method A.Show()
Method A.ShowA()
-------------------
Method B.Show()
Method A.ShowA()
Method B.ShowB()
-------------------
Method C.Show()
Method A.ShowA()
Method B.ShowB()
Method C.ShowC()

 

3. A reference to the base class in the class hierarchy. Features of using

As you know, a reference to any class can be declared. If classes form an inheritance hierarchy, then the following rule can be defined for these classes (rule 1): a reference to the base class can be assigned the value of the instance (object) of the derived class. That is, after a reference to the base class is declared, this reference can be assigned the values of an object (instance) of any class from the hierarchy. Thus, you can “move” with the help of a reference to the created class instances from the hierarchy.

Figure 2 shows rule 1 using an example of a hierarchy of 3 classes A, B, C.

C#. Inheritance. Assigning a reference to a base class of values of instances of derived classes

Figure 2. Assigning a reference to a base class of values of instances of derived classes

After the reference to the base class is assigned the values of one of the class instances from the hierarchy, you can try to use the elements of this instance (call methods, properties, etc.). In this case, there is a rule 2: if the reference to the base class receives the value of the object (instance) of the derived class, then access to this reference is only to the elements of the base class. Figure 3 shows the use of rule 2.

C#. Inheritance. Access to elements of classes using a reference to base class

Figure 3. Access to elements of classes A, B using rA reference to base class A

As can be seen from Figure 2, using the reference to the base class, you can access the elements of the base class A. There is no access to elements of base class B. To organize access to the elements of an inherited class B, you need to use methods of cast type A to type B (see paragraph 5).



 

4. An example that demonstrates the limitations that may arise when using a base class reference

The example demonstrates the restrictions on access to the elements of the objB instance of the derived class B from the reference rA to the base class A. It is impossible to call elements of class B without explicitly casting and using the is and as operators.

using System;
using static System.Console;

namespace C_sharp
{
  // Class A - base class
  class A
  {
    public void Show()
    {
      WriteLine("Method A.Show()");
    }

    public void ShowA()
    {
      WriteLine("Method A.ShowA()");
    }
  }

  // Class B - inherited class from class A
  class B : A
  {
    public void Show()
    {
      WriteLine("Method B.Show()");
    }

    public void ShowB()
    {
      WriteLine("Method B.ShowB()");
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // 1. Reference to base class
      A rA;

      // 2. Instance of class A
      A objA = new A();

      // 3. Instance of class B
      B objB = new B();

      // 4. A base class reference can be assigned
      // a base class reference value - this is natural
      rA = objA;

      // 5. Using items by reference
      rA.Show(); // A.Show() is called
      rA.ShowA(); // A.ShowA()
      // rA.ShowB(); // - error, there is no access to ShowB()

      // 6. A base class reference can be assigned
      // a derived class reference value (rule 1)
      rA = objB; // rA referc to the instance objB of class B
      rA.Show(); // A.Show() is called again - important
      rA.ShowA(); // A.ShowA()
      // rA.ShowB(); // error, again no access to ShowB()

      // to call B.Show (), you must explicitly
      // cast the rA reference to type B.
    }
  }
}

The program result

Method A.Show()
Method A.ShowA()
Method A.Show()
Method A.ShowA()

 

5. Ways to organize access to elements of a derived class using a reference to the base class. Keywords is, as

As it was defined in the previous paragraph, if a reference to a base class refers to an instance of a derived class, then using this reference there is access only to elements of the base class. However, this rule can be changed and access to elements of derived classes. In order to access an element of a derived class using a reference to a base class, you need to use one of three possible methods:

  • use an explicit cast to the type of the inherited class;
  • use the as keyword, which attempts to cast one type to another;
  • use the as keyword in conjunction with type compatibility checking. The compatibility check uses the is keyword.

Figure 4 shows all 3 methods for the given classes A, B which form a hierarchy.

C#. Inheritance. Ways of access of a derived class elements using a reference to base class

Figure 4. Ways of access of a derived class elements using a reference to base class

 

6. An example that demonstrates how to organize access by reference to elements of a derived class.

The example demonstrates 3 ways to organize access to the Show() method of a derived class B from a reference to base class A. The implemented methods demonstrate static polymorphism when a uniform method call is formed at the compilation stage (during type casting).

using System;
using static System.Console;

namespace C_sharp
{
  // Class A - base class
  class A
  {
    public void Show()
    {
      WriteLine("Method A.Show()");
    }

    public void ShowA()
    {
      WriteLine("Method A.ShowA()");
    }
  }

  // Class B - inherited from class A
  class B : A
  {
    public new void Show()
    {
      WriteLine("Method B.Show()");
    }

    public void ShowB()
    {
      WriteLine("Method B.ShowB()");
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      // 1. Reference to the base class
      A rA;

      // 2. The instance of class A
      A objA = new A();

      // 3. Instance of class B
      B objB = new B();

      // 4. Access to the item of instance objA
      rA = objA;
      rA.Show(); // A.Show() is called
      rA.ShowA(); // A.ShowA()
      // rA.ShowB(); - error, access denied

      // 5. Access to the items of instance objB
      // using reference to A
      rA = objB; // rA refers to objB

      // 5.1. Way №1. Cast to type B - it is necessary,
      // that the call rA.Show() => objB.Show()
      try
      {
        // cast rA to type B
        ((B)rA).Show(); // B.Show() is called
      }
      catch
      {
        // If cast rA to type B did not take place,
        // then exit
        WriteLine("Error.");
        return;
      }

      // 5.2. Way №2. Using the as keyword.
      // The as keyword is used when you need to try
      // to cast one type to another.
      rA = objB;
      if ((rA as B) != null)
        (rA as B).Show(); // B.Show()

      // 5.3. Way №3. Using a combination of keywords is, as.
      // The is keyword is used to determine
      // the compatibility of two types. If the types
      // are compatible, then the result is true, otherwise false.
      if (rA is B)
        (rA as B).Show(); // B.Show()
    }
  }
}

 


Related topics

 


 

0
fb-share-icon20