Abstract class inheritance

I have multiple pages using the same code in a constructor as follow:
class LoginPage
    {
        public LoginPage(IWebDriver driver)
        {
            PageFactory.InitElements(driver, this);
        }
    }
class EmployeePage
 {
        public EmployeePage(IWebDriver driver)
        {
            PageFactory.InitElements(driver, this);
        }
 }

Open in new window

so I created a abstract base class first
public abstract class BasePage
    {
        public BasePage(IWebDriver driver)
        {
            PageFactory.InitElements(driver, this);
        }
    }

Open in new window


And then let other classes inherit this code instead of using the same code to each pages.
class LoginPage:BasePage
    {
        public LoginPage(IWebDriver driver): base(driver)
        {
        }
}

Open in new window


After I created a Login object, what's happening?
LoginPage lp = new LoginPage(_driver);

Open in new window


_driver is passed to LoginPage constructor which will call BasePage constructor.
It executes the code inside BasePage constructor and then execute the code inside LoginPage constructor.

Here is my question:
when it executes the code inside Base constructor with _driver, this will execute the following code for a base class, NOT for LoginPage class.
So it ends up initialize BasePage class NOT LoginPage class. I know that my logic is wrong. Can you please explain how executing the code in a base class initialize LoginPage class?
PageFactory.InitElements(_driver, this);

Open in new window

IsabellAsked:
Who is Participating?
 
sarabandeConnect With a Mentor Commented:
So it ends up initialize BasePage class NOT LoginPage class.
your logic is incorrect since public inheritance means that LoginPage "IS" a BasePage, like a rabbit "IS" an animal and an animal "IS" a living being.

you may look at BasePage as a part of a LoginPage. actually this exactly is the case if both BasePage and LoginPage have data members. then you have a contiguous base structure with all BasePage members and an enlargement of the structure with all members of the LoginPage.

since c# doesn't support multiple inheritance, the 'this' 'points' to the begin of the memory object which starts with baseclass members followed by derived class members. so the 'this' points to both objects the smaller baseclass object and the larger derived class object and it is always the same object.

Sara
0
 
Guy Hengel [angelIII / a3]Billing EngineerCommented:
I think that all you need to understand is that inside of :
PageFactory.InitElements(driver, this);
you need to check eventually the "GetType" of the passed object, to know it's exact class:
https://msdn.microsoft.com/en-us/library/system.object.gettype.aspx

I hope this is the point you are missing, as otherwise inheritance and calling a base constructor is "simple" ...
0
 
it_saigeDeveloperCommented:
To illustrate Sara's point, consider the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace EE_Q28964050
{
	class Program
	{
		static void Main(string[] args)
		{
			Animal critter = new Animal() { HasClaws = true, HasTeeth = true, IsHairy = true };
			Rabbit pet = new Rabbit() { HasClaws = true, HasTeeth = true, IsHairy = true, Name = "Fluffy" };

			Console.WriteLine("Is critter an Animal? {0}", critter.GetType().Equals(typeof(Animal)));
			Console.WriteLine("Is critter a Rabbit? {0}", critter.GetType().Equals(typeof(Rabbit)));
			critter.PrintProperties();

			Console.WriteLine();

			Console.WriteLine("Is pet an Animal? {0}", pet.GetType().Equals(typeof(Animal)));
			Console.WriteLine("Is pet a Rabbit? {0}", pet.GetType().Equals(typeof(Rabbit)));
			pet.PrintProperties();
			Console.ReadLine();
		}
	}

	class Animal
	{
		public bool IsHairy { get; set; }
		public bool HasTeeth { get; set; }
		public bool HasClaws { get; set; }
	}

	class Rabbit : Animal
	{
		public string Name { get; set; }
	}

	static class Extensions
	{
		public static void PrintProperties<T>(this T source)
		{
			if (source != null)
			{
				Console.WriteLine("Displaying properties for {0}", typeof(T).Name);
				foreach (PropertyInfo property in typeof(T).GetProperties())
					Console.WriteLine("Name: {0}; Value: {1}", property.Name, property.GetValue(source, null));
			}
		}
	}
}

Open in new window

Which produces the following output -Capture.JPG
-saige-
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

 
sarabandeCommented:
Is pet an Animal? False

better:  Is pet an unknown or unspecified animal? False // no, it truly is a rabbit

;-)

Sara
0
 
it_saigeDeveloperCommented:
You twisted my arm Sara...  ;).  Revised code to determine if instance derives from base class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace EE_Q28964050
{
	class Program
	{
		static void Main(string[] args)
		{
			Animal critter = new Animal() { HasClaws = true, HasTeeth = true, IsHairy = true };
			Rabbit pet = new Rabbit() { HasClaws = true, HasTeeth = true, IsHairy = true, Name = "Fluffy" };

			Console.WriteLine("Is critter an Animal? {0}", critter.GetType().Equals(typeof(Animal)) || critter.GetType().BaseType.Equals(typeof(Animal)));
			Console.WriteLine("Is critter a Rabbit? {0}", critter.GetType().Equals(typeof(Rabbit)));
			critter.PrintProperties();

			Console.WriteLine();

			Console.WriteLine("Is pet an Animal? {0}", pet.GetType().Equals(typeof(Animal)) || pet.GetType().BaseType.Equals(typeof(Animal)));
			Console.WriteLine("Is pet a Rabbit? {0}", pet.GetType().Equals(typeof(Rabbit)));
			pet.PrintProperties();
			Console.ReadLine();
		}
	}

	class Animal
	{
		public bool IsHairy { get; set; }
		public bool HasTeeth { get; set; }
		public bool HasClaws { get; set; }
	}

	class Rabbit : Animal
	{
		public string Name { get; set; }
	}

	static class Extensions
	{
		public static void PrintProperties<T>(this T source)
		{
			if (source != null)
			{
				Console.WriteLine("Displaying properties for {0}", typeof(T).Name);
				foreach (PropertyInfo property in typeof(T).GetProperties())
					Console.WriteLine("Name: {0}; Value: {1}", property.Name, property.GetValue(source, null));
			}
		}
	}
}

Open in new window

Now produces the expected (and really correct output) -Capture.JPG-saige-
0
 
IsabellAuthor Commented:
Sara,

I really like your explanation:

since c# doesn't support multiple inheritance, the 'this' 'points' to the begin of the memory object which starts with baseclass members followed by derived class members. so the 'this' points to both objects the smaller baseclass object and the larger derived class object and it is always the same object.

Thanks!
0
 
IsabellAuthor Commented:
sorry for the late acceptance. I thought that I did selected your answer long time ago.
Thank you again, Sarabande!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.