Reputation:
I have class Person
, two child classes Staff
and Student
, interface IPerson
. Also I have a class Database
and class Gateway
. Class Database
has
private string id = "username";
and method
public void getID() {return id;}
Both Staff and Student have getID() methods. Gateway has to check if method getID() was requested by Staff
(return id
) or Student
(return "Go away!"
).
Can anyone please help me with that. I was thinking about using Gateway
as an interface of Database
class, but because I am only trying to learn C#, I don't really know how to do that. Or maybe there's a better way of doing this... Please help
Thanks
here's some code:
public class Staff : Person
{
public Staff() {}
public Staff(string id): base(id) {}
public override string getName()
{
throw new NotImplementedException();
}
public override void Update(object o)
{
Console.WriteLine(id + " notified that {1}", id, o.ToString());
}
public override void UpdateMessage(object p)
{
Console.WriteLine(id + " notified about new message in chat: {1}", id, p.ToString());
}
}
public class Student : Person
{
public Student() {}
public Student(string id): base(id) {}
public override string getName()
{
throw new NotImplementedException();
}
public override void Update(object o)
{
Console.WriteLine(id +" notified that {1}", id, o.ToString());
}
public override void UpdateMessage(object p)
{
Console.WriteLine("Message for " + id + " {1}", id, p.ToString());
}
}
public abstract class Person : IPerson
{
string id;
public Person() { }
public abstract string getName();
public Person(string i) { this.id = i; }
public abstract void Update(Object o);
public abstract void UpdateMessage(Object p);
}
public interface IPerson
{
void Update(Object o);
void UpdateMessage(Object p);
string getName();
}
class database
{
public string username = "username";
private string name = "user details";
private string grade = "user grade";
public string getName(Object o)
{
if (o is Staff) { return name; }
else { return "Go away!"; }
}
public string getgrade() { return grade; }
}
public class Gateway
{
public void DoSomethingWithPerson(IPerson person)
{
string iD = person.getName();
if (person is Student)
{
return "go away!";
}
else if (person is Staff)
{
return name;
}
}
}
Upvotes: 0
Views: 705
Reputation: 54781
I would discourage is
chains altogether. It violates Liskov. In short, this means it is hard to add a new IPerson
implementation without modifying Gateway
to cope with that new type. Or it forces developers to descend from one of the existing types to implement a new IPerson
, in which case, what is the point of the interface over just the abstract Person
type?
public class Gateway
{
public string DoSomethingWithPerson(IPerson person)
{
return person.DoSomething();
}
}
//then IPerson implementors like Student can provide the custom behaviour.
public class Student : Person
{
public string DoSomething()
{
return "Go Away!";
}
...
}
Upvotes: 1
Reputation: 9009
I suppose you have something similar in your Gateway class:
public class Gateway
{
public void DoSomethingWithPerson(IPerson person)
{
string id = person.getID();
if (person is Student)
{
// do stuff for student, even cast is possible (Student) person
}
else if (person is Staff)
{
// do stuff for staff, even cast is possible (Staff) person
}
}
}
The code above assumes that getID()
returns the string id (you have public void getID()
in the state of the question at the moment of this answer).
A note on the is
keyword
The is
keyword allows for checking at runtime the type of an object. This works for interfaces, classes and structs. If you have hierarchy and exclusive conditions, you must be careful, since the following code:
if (person is Person)
{
return;
}
else if (person is Student)
{
// do student stuff
}
will never "do student stuff" when you have passed a Student
instance, since person is Person
is true for any instance of Student
because Student
extends Person
. To overcome this, use the concrete type checks before the more-abstract one:
if (person is Student)
{
// do student stuff
}
else if (person is Person)
{
return;
}
Upvotes: 0