Solved

Abstract class inheritance

Posted on 2016-08-17
7
132 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 33

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 33

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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 33

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 33

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

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Visual Studio 2013 and Eclipse Neon 6 38
VB.NET (2008) - Refactoring Question 2 21
Hey!! 5 33
Winform Module - What is the ASP.Net equiv 2 23
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
The article shows the basic steps of integrating an HTML theme template into an ASP.NET MVC project
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.

803 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