Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Abstract class inheritance

Posted on 2016-08-17
7
Medium Priority
?
155 Views
Last Modified: 2016-08-30
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

0
Comment
Question by:Isabell
  • 2
  • 2
  • 2
  • +1
7 Comments
 
LVL 143

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 41760587
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
 
LVL 35

Accepted Solution

by:
sarabande earned 2000 total points
ID: 41760902
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
 
LVL 35

Expert Comment

by:it_saige
ID: 41761247
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
NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

 
LVL 35

Expert Comment

by:sarabande
ID: 41761292
Is pet an Animal? False

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

;-)

Sara
0
 
LVL 35

Expert Comment

by:it_saige
ID: 41761470
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
 

Author Comment

by:Isabell
ID: 41763363
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
 

Author Closing Comment

by:Isabell
ID: 41777311
sorry for the late acceptance. I thought that I did selected your answer long time ago.
Thank you again, Sarabande!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…
Suggested Courses

580 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question