Hi,
I am hoping someone can explain this to me.
Lets say I have an abstract class called Employee, from Employee, the following classes are inherited, Manager and Cleaner
Can someone explain to me how to incorporate an Interface for this scenario so my application can tell which type of object "Manager or Cleaner" its dealing with
Thanks

Interfaces and Abstract Classes
srlito
Ok,
You may create an interface just called Login to define the login issue (get and set the password etc.). Then all the employee inherited the interface. That's my idea about it.
Thank you
Haziman
Hi, authentication method must not be in abstract class,
See in my previous post,
<authenticationclass or simply common USER class object>.authenticate(userid, pass)
Authentication is a common code used by your presentation layer so it must be somewhere in Business login layer and that "BLL" object should be used by the presentation layer (Form) to authenticate the user. So till you call this method, no need to create Employee object but this authentication method should return the Employee class with filled in info
HTH,
Mateusz Rajca
Hi,
IMHO, here in your case, interface is not needed looking at your requirements. The abstract class serves best in the case.
Why
- each employees will have their details like name, address, joining date, salary etc. These info is not specific to Manager or Cleaner but applicable to both
- Now these details related implementation can be common and thats why it should go into Employees.
Now when Interface required
- When you need to implement some method of same singature but with COMPLETELY DIFF IMPLEMENTATION for various classes then you should go for interfaces.
- e.g. In this example, (just as example) lets say i have IEmployee interface having "string JobDetails()" method which returns "job description of specific type of employee" so Manager and Cleaner will have diff duties and that may be differ in implementation so we can implement this interface and provide diff impl details
- Also, if some manager specific items is there then you can use IManager interface .. lets say having "Employees[] GetPersonWorkingUnderManager()" - this is only required in Manager but not in Cleaner
Now another point of your question,
If you want to know the details of an Employee after login then if you can have a method with common implementation under Employee (abstract class) which returns detail of an employee - doesnt matter which type of employee is there. Because this is applicable to both same way.
So, If you have employee type specific thing then you should use interface - even in that case too, you dont need to go for interface, you can use abstract methods (just providing declaration of method and let derived class implement it their own)
Also, Only one abstract class can be inherited in derived class so if you have multiple diff set of requirement then you should use diff interface for each type of set of requirements.
Hope, it serves the purpose,
If you have more questions or want more clarifications then please inform,
HTH,
Byenary
I understand what you are saying but there is no way for me to know what kind of employee logged in before going into the database.
Since the employee class is an abstract class I cant say
Employee emp= new Employee()
emp.authenticate();
if(emp.PositionID==1) //Manager
{
frmManager managerForm= new frmManager();
managerForm.Show();
}
thats why I was thinking of using an interface
Josh Holmes
PositionID is stored at the database level and its a property in the abstract Class.
In the login form, I am geeting the userid and password from the user
txtuname, txtpassword, and send them to an sp to authenticate the user without using an objects
This is the code for the login
cmd.Connection = Config.objConn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "spLogin";
cmd.Parameters.AddWithValue(" Uname" , this.txtUserName.Text);
cmd.Parameters.AddWithValue(" Pass" , this.txtPassword.Text);
using(SqlDataReader oDr=cmd.ExecuteReader(CommandBehavior.CloseConnection))
if (oDr.Read())
{
Config.EmployeeNum = oDr.GetInt32(oDr.GetOrdinal("Employee_Number"));
Config.accessLevel = oDr.GetInt32(oDr.GetOrdinal("PositionID"));
Config.TeamID = oDr.GetInt32(oDr.GetOrdinal("TeamID"));
Config.currentID = oDr.GetString(oDr.GetOrdinal("CorpID"));
switch (Config.accessLevel)
{
case 1:
frmMgr frmManager = new frmMgr();
frmManager.Text += " " + oDr.GetString(oDr.GetOrdinal("First_Name")) + " ";
frmManager.Text += oDr.GetString(oDr.GetOrdinal("Last_Name"));
frmManager.MdiParent = this.MdiParent;
frmManager.Show();
this.Close();
break;
case 2:
frmTr frmTrainer = new frmTr();
frmTrainer.Text += " " + oDr.GetString(oDr.GetOrdinal("First_Name")) + " ";
frmTrainer.Text += oDr.GetString(oDr.GetOrdinal("Last_Name"));
frmTrainer.MdiParent = this.MdiParent;
frmTrainer.Show();
this.Close();
break;
case 3:
frmTl frmTeamLead = new frmTl();
frmTeamLead.Text += " " + oDr.GetString(oDr.GetOrdinal("First_Name")) + " ";
frmTeamLead.Text += oDr.GetString(oDr.GetOrdinal("Last_Name"));
MdiParent = this.MdiParent;
frmTeamLead.Show();
this.Close();
break;
default:
frmAn frmAnalyst = new frmAn();
frmAnalyst.Text += " " + oDr.GetString(oDr.GetOrdinal("First_Name")) + " ";
frmAnalyst.Text += oDr.GetString(oDr.GetOrdinal("Last_Name"));
frmAnalyst.MdiParent = this.MdiParent;
frmAnalyst.Show();
this.Close();
break;
}
}
else
{
MessageBox.Show("Invalid User Name or Password",Application.ProductName.ToString(),
MessageBoxButtons.OK,MessageBoxIcon.Error);
}
Now I am using Config.accessLevel which is a public static variable to redirect the users to the proper form.
I am thinking there has to be a better way to do this instead of using these static variables
something like creating an authentication method in the Abstract Class or using an interface to do it.
Poojari
Hi,
So PositionID is defined for each specific employee type
I mean let say PositionID values for Manager has 1, TeamLead has 2, Supervisor has 3 etc
If so then you just use that to open specific form using switch case. So in this case as PositionID is part of Employee class, you dont need to worry which concrete class is there when you do this job,
If i am wrong understanding PostionID but its just like "userid" then also you dont need any interface,
as in previous post some has suggested, you can use something like;
foreach(Employee emp in employees) {
if(emp is Manager)
{ ....
ManagerForm.Show();
....
} else if (emp is TeamLead) {
...
}
:
:
}
This should work fine,
Or
emp.GetType().ToString() will give you Fully qualified class name so you can use string comparison with that and will do the job,
Also, I would like to add one more thing that Interfaces are for higher level abtraction and what you are looking for is opposite to that means you want to know the low level information about object type...
HTH,
KHodam
What I am trying to do is something like this.
after the employee logs in the with username and password, I want to be able to use retrieve all of his/her information. all employees inherit from the abstract class. I am convinced now that the best way to do this is by using an interface along with the abstract class but still can not think of a clear way of writting the code for it.
Ofir Epstein
I understand the concept of abstract classes better now. let me just explain what I am trying to do here.
I have the abstract class employee with fname, lname, salary and PositionID and so on, all other classes inherit from this class "TeamLead, Manager, Supervisor, Maintenance, and Trainer"
they all share the same properties fname,lnane and salary.
all these users use the same login form.
what I need to know is this. Is it possible to create an interface to tell me what kind of me what kind of employee logged in "manager, teamlead" so I can open the proper form for them and still use polymorphism
all employees access is based on their PositionID
Thanks
tanis15063
Hi,
what are you trying to achieve. The beauty of abstract classes are that you should not have to know what concrete type of object you are dealing with most of the time, you have some common interface which is defined in the abstract class which you call on the concrete instances i.e. a classic example would be:
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Circle circle = new Circle();
Square square = new Square();
Shape[] shapes = new Shape[] { circle, square };
DrawShapes(shapes);
}
public static void DrawShapes(Shape[] shapes)
{
//Do not care what shapes they are all this methods cares
//about that it is responsible for drawing them all
foreach(Shape shape in shapes)
{
shape.Draw();
}
}
}
abstract class Shape
{
public abstract void Draw();
}
class Square : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing square");
}
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing circle");
}
}
}
If you really want to know the type then you can just do the following:
MyClass x = new MyClass();
if(x is MyClass)
{
}
Mark.
Javahar
Hi, Sammy
If you want to check if an object is compatible with a given type just use is keyword as mark said.
Thanks
GrayMatter Software
Hi,
well this is my thought on interfaces and abstract classes, you want to have an abstract class when concrete classes will be sharing similar implementation details, like each employee has a name, that field can be stored in the abstract class and also the property to access that information can be in the abstract class. So when you have similar classes that will share code use an abstract class, however if you have classes that are nothing to do with one another but share some aspect that they do not share a common ancestor then use an interface. A good example of this is the IDisposable interface, you use this when an object has some internal resource that needs to be explicitly cleaned up as soon as possible, so the interface has a single method called Dispose, now you can apply this to any object since all objects will be different in how they dispose of their internal state, but you still want to be able to call objects as IDisposable types, hope that makes sence.
An example of what I would do if I was you is shown below:
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Cleaner c = new Cleaner("bob", 5000);
Manager m = new Manager("mike", 100000);
Employee[] employees = new Employee[] { c, m };
PrintEmployeeDetails(employees);
}
static void PrintEmployeeDetails(Employee[] employees)
{
foreach (Employee employee in employees)
{
Console.WriteLine("Name=" + employee.Name + ", Salary=" + employee.Salary);
}
}
}
abstract class Employee
{
private string name;
private int salary;
protected Employee(string name, int salary)
{
this.name = name;
this.salary = salary;
}
public string Name
{
get
{
return this.name;
}
}
public int Salary
{
get
{
return this.salary;
}
}
}
class Manager : Employee
{
public Manager(string name, int salary)
: base(name,salary)
{
}
}
class Cleaner : Employee
{
public Cleaner(string name, int salary)
: base(name, salary)
{
}
}
}
Mark.
lms07424
see my code in my previous post
thanks
dream4jung
Hi,
You will need to open form after authenticating the person so when you are going to database for authentication, why you are not getting more information in Employee class after authentication
I mean to say, lets you are calling some method from your login page to database for authentication and you are passing credentials to that method. So if its successfull authentication then get the PositionID at the same time and create the object you want based on PositionID and make the return type of that method as Employee so after authentication, the BLL class can return Employee object and you can do above job.
I mean on <authenticationclass or simply common USER class object>.authenticate(userid, pass) it will fill up PositionID after successfull authentication and so you can use the rest of code you wrote to check PositionID as explained above.
HTH,
Fred Bernstein
As Indian Ocean Said I also agree with him that you do not need the use of Interfaces here. Abstract classes will do the pretty job.
And then when you need to check the type of the object that an Abstract class's object originally holds then the better choice is to use "as" keyword if you want to do processng on that type otherwise "is" will do the pretty god job.
Here:
Employee emp = new Programmer();
Director dir = emp as Director; // It was not the case so it'll simply assing the dir a null reference
if(dir == null) // it was not a Director's object
{
}
else
{
// Yes it was
int salary = dir.Salary;
}
Why prefer the use of as on is
because using is duplicates the parsing effort on CPU once you check type using "is" it'll try to parse and if successfull then returns true. Then seeing the true you use as object which will do the parsing again.
So using as once ensures that you are not replicatng the work.
I hope this will help.
Best regards,
Rizwan aka RizwanSharp