Solved

Abstract class inheritance

Posted on 2016-08-17
7
125 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 142

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 32

Accepted Solution

by:
sarabande earned 500 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 32

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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 32

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 32

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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

747 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now