Object-Oriented Programming - c#

I am new to C#. I have a Persons class with this function:
public virtual void InputPerson(Persons P)
{
P.ID = int.Parse(Console.ReadLine());
Console.WriteLine("Titel:");
P.Titel = Console.ReadLine();
Console.WriteLine("Name:");
P.Name = Console.ReadLine();
Console.WriteLine("Surname:");
P.Surname = Console.ReadLine();
}
And I have a User class that inherits form this Persons class. I now need to create a InputUser function in the User class that makes use of this InputPerson function in the Persons class without rewriting all the code from the InputPerson function to the InputUser function. Here is my code from the InputUser function:
public override void InputPerson(User U)
{
Console.WriteLine("Please enter a Customer:");
Console.WriteLine("Customer ID:");
base.InputPerson;
Console.WriteLine("Telephone Number:");
U.Telephone = int.Parse(Console.ReadLine());
Console.WriteLine();
}
This InputUser code gives me a error stating:
'UserCustomerNotes.User.InputPerson(UserCustomerNotes.User)': no suitable method found to override
Can anyone please help?
Thanks in advance

base.InputPerson; cannot work at all.
You cannot override void InputPerson(Persons P) with void InputPerson(User U) as you seem to imply. The signatures must be identical.

This is just me taking more tangential look at this question but under the traditional guidelines for OO design a user is a person therefore you get inheritance. However, when we look at SOLID principles and especially the "Liskov Substitution Principle":
"Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it." — Robert Martin, LSP paper linked from The Principles of OOD
What does that mean? Well, we should be able to substitute an instance of a subclass for its parent class and everything should continue to work. In this case it won't work, there are extra properties that you are depending on for User that a Person does not have.
In this case have you considered doing composition rather than inheritance?
public class Person
{
public static void InputPerson(Person p)
{
// Do the input logic here
}
}
public class User
{
public Person Person { get; private set; }
public static void InputUser(User u)
{
if (u.Person == null)
u.Person = new Person;
Person.InputPerson(u.Person);
Console.WriteLine("Telephone:");
u.Telephone = Console.ReadLine();
}
}
We could go further into SOLID and take a look at the Single Responsibility Principle and ask is the Person/User object handles the logic of being a person but should it know about creating that object from the console? What happens if you want to re-use the same logic for a windows application or a WPF application?

To override a method you must keep its signature, which you dont(you change the type of the parameter from Persons to User, so you create a new method). So remove the 'override' keyword.
Also, use:
InputPerson(U);
Instead of:
base.InputPerson;

You could also do the following, taking advantage of the class inheritance:
public override void InputPerson(Persons P)
{
// Code in here
}
Because a User is a Persons, then you are allowed to directly pass it into the Method as a parameter. If however there are
custom Properties on a User that are not present on a Persons you could introduce generics.
public class Persons<T>
{
public virtual void InputPerson(T p)
{
// code here.
}
}
public class User : Person<User>
{
public override void InputPerson(User p)
{
// code here. You can now treat the input as a user
// as you have told your base class that the 'T' is a user.
}
}

Instead of overriding the method, use the new keyword instead as the signatures are different.
public new void InputPerson(User U)
Then all you need to do is pass User U through to the base class, so instead of
base.InputPerson;
use
base.InputPerson(U);

Related

How to name these helper functions?

public class Member
{
Team team;
int p;
public void GoToTeam(Team team) // how to name it? MS tells me not to add __
// I want to prevent this be called so easily by mistake
{
this.team = team;
p = team.GetHashCode(); // some setup for team changing, new id, new title, etc
}
}
public class Team
{
List<Member> members = new();
public void AddMember(Member member) // main func.
// Team moves people. How about Street? street don't move people
{
members.Add(member);
// and something more, member maps etc
}
}
Member has a GoToTeam function, which cannot work alone, without being called by functions like AddMember.
How to name these helper function in c#, to prevent it to be called alone by mistake?
A good class design would help. Like always Team do action to lower hierachies.
But member is the basic action unit. Do I need a ugly member.AddTeam_wrapper()?
Is there a more straightforward way to do this?
Like __GoToTeam in other languages.
I'm working on composite patterns.
A lot of classes are hierachically structured.
Methods are used to change their relationship.
It's easy to use a half-function by mistake, without a detailed documentation.
In some languages, you use friend class private, __goto method, to prevent these methods to be used.
Again, I'm not so good at designing these not so tiny modules, as MS expected :(
When geo-layers, bio-layers, political-layers comes, it's to messy to have one prime rule to identify the Main function, which calles other (I call it) half-functions.
I want a good naming convention to identify these public methods and public but not standalone methods.
Thank you!
First of all, if the naming conventions are one of your concerns, you should change AddMember_wrapper to AddMemberWrapper.
Then, you should consider one of your classes as something like a parent and do any of your actions through it. In this case, you can consider Team as a parent and Member will be one of its Children(AggregateRoot Pattern). If you want to set a Team for a Member, you should do it another way around and add the Member to a Team.
public class Team
{
public List<Member> Members { get; private set; }
public Team()
{
Members = new List<Member>();
}
public void ChangeMemberName(int memberId, string newName)
{
Member member = Members.SingleOrDefault(x => x.Id == memberId);
if (member is null)
throw new ArgumentException("Member not found.");
member.ChangeName(newName);
}
public void AddMember(Member member)
{
Members.Add(member);
// and something more, member maps, etc
}
}
public class Member
{
public int Id { get; private set; }
public string Name { get; private set; }
// ...
public Member(string name)
{
Name = name;
}
public void ChangeName(string newName)
{
Name = newName;
}
}

C# Can't access class instance from different method than it was instantiated in

The problem I have may be a fairly obvious one but im new to c# and coding in general. I have looked around online but I couldn't find anything that could help me. This is a demo code I prepared for the situation im in.
class Program
{
class Person //The class
{
public string jobTitle = "Cashier";
public void Greet()
{
Console.WriteLine("Hi, im bob.");
}
}
public static void Main(string[] args) //Method it was instantiated in
{
Person Bob = new Person();
Bob.Greet();
}
public static void OtherMethod() //Method I want to access it in
{
Bob.Greet();
Console.WriteLine(Bob.jobTitle); //"'Bob' does not exist in the current context"
}
}
This is a serious problem for me because im working on something that has alot of classes and I am forced to use temp variables to transfer the class data from Main() into the parameters of another method. Also on a side note, none of the data im trying to access is static. I can access it in Main().
I just want to know if im missing something here?
there is no meaning of having class inside class (Person class in Program class)
if you need to access Bob within same class check the code below
public class Person
{
public string jobTitle = "Cashier";
public void Greet()
{
Console.WriteLine("Hi, im bob.");
}
}
public static class Program
{
private Person _bob;
public static void Main(string[] args)
{
_bob = new Person();
_bob.Greet();
OtherMethod();
}
public static void OtherMethod()
{
_bob.Greet();
Console.WriteLine(_bob.jobTitle);
}
}
The problem I have may be a fairly obvious one but I'm new to c# and coding in general.
It is an obvious problem, but it is also a problem common to beginners; we were all beginners once!
I have looked around online but I couldn't find anything that could help me.
You would likely benefit from a more focussed course of study than just browsing the internet and hoping for the best. Consider investing in a good beginner book.
I am forced to use temp variables to transfer the class data from Main() into the parameters of another method
That is normal and good when not taken to extremes. When taken to extremes, the pattern you are describing is called "tramp data", because you end up "tramping around" data from method to method.
Programmers who try too hard to avoid tramp data end up in a bad pattern at the other end of the spectrum: relying on global state.
There is no one magic way that is "always right". However it is generally accepted that a method's actions and return values should depend mostly on their arguments; remember that "this" is logically an argument.
Let's look at your code and get you out of bad habits while you are still a beginner.
class Program
{
class Person
{
Nested classes are legal in C# but are most often used for advanced scenarios where types are implementation details of other types. Break this up into two non-nested classes.
class Person
{ ... }
class Program
{ ... }
Let's look at Person:
class Person //The class
Do not leave comments that explain what is obvious. class Person is obviously a class; you don't have to say it again. My guideline is to write code so clearly that it does not need a comment explaining what it does. Use comments to explain why code has to exist.
{
public string jobTitle = "Cashier";
Public fields are a bad programming practice in C#. Use a public property, and CaseItLikeThis. In C# 7, that's very concise:
public string JobTitle => "Cashier";
In earlier versions of C# you'd say
public string JobTitle { get { return "Cashier"; } }
Moving on:
public void Greet()
{
Console.WriteLine("Hi, im bob.");
}
}
Good programmers pay close attention to even the smallest details.
Console.WriteLine("Hi, I'm Bob.");
All right, that does it for Person.
Your problem in Program that you are actually asking about is that OtherMethod can't see local variable Bob -- which should be renamed bob; local variables are casedLikeThis.
There are three ways you'd typically solve that.
Pass bob as an argument; make OtherMethod take a Person as a formal parameter.
Make bob a private static field. Assign the field in Main, and use it from OtherMethod.
Make bob a private instance field. Create a new Program(), assign the bob field, and make OtherMethod an instance method. You can then access this.bob from OtherMethod.
My advice to you is: write the program all three ways. This will be good practice.
your problem is a matter of scope and context. It's common to have these problems at first starting with programming.
Pointing out why you cannot access Bob in the second method:
class Program
{
class Person //The class
{
public string jobTitle = "Cashier";
public void Greet()
{
Console.WriteLine("Hi, im bob.");
}
}
public static void Main(string[] args) //Method it was instantiated in
{
// Bob is instantiated local to the main method
Person Bob = new Person();
Bob.Greet();
//You didn't call OtherMethod() here
}
public static void OtherMethod() //Method I want to access it in
{
// Since Bob was not passed in as a parameter or accessible via a global var, here you dont have access to it. access it
Bob.Greet();
Console.WriteLine(Bob.jobTitle); //"'Bob' does not exist in the current context"
}
}
Here, building on your example, a version that works:
class Program
{
static Person GlobalBob; // must be static because we are instantiating it inside a static method
class Person
{
public string jobTitle = "Cashier";
public void Greet()
{
Console.WriteLine("Hi, im bob.");
}
}
public static void Main(string[] args) //Method it was instantiated in
{
GlobalBob = new Person();
GlobalBob.Greet();
OtherMethod(); //Call your OtherMethod here otherwise it's not gonna be executed
}
public static void OtherMethod() //Method I want to access it in
{
GlobalBob.Greet();
Console.WriteLine(GlobalBob.jobTitle); //Here we have access to GlobalBob
Console.ReadLine(); //Wait for you to press a key so you can read the output !
}
}
Hope it helps!

Why should I want to create an object with base class reference?

public class BaseClass
{
public virtual void Display()
{
Console.WriteLine("I am Base Class");
}
public void BaseClassMethod()
{
Console.WriteLine("I am Base Class Method");
}
}
public class DerivedClass : BaseClass
{
public override void Display()
{
Console.WriteLine("I am Derived Class");
}
public void DerivedClassMethod()
{
Console.WriteLine("I am Derived Class Method");
}
}
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
bc.Display();
bc.BaseClassMethod();
Console.WriteLine("--------------");
DerivedClass dc = new DerivedClass();
dc.Display();
dc.BaseClassMethod();
dc.DerivedClassMethod();
Console.WriteLine("--------------");
BaseClass bc2 = new DerivedClass();
bc2.Display();
bc2.BaseClassMethod();
//bc2.DerivedClass(); --> I can't reach b2.DerivedClass() method
Console.ReadLine();
}
}
Hi everyone. I am trying to clear my mind about Why and where would I want to create and use derived class object from base class reference. I know how virtual works. I know derived class is a base class and I can override virtual methods. I can reach non virtual methods in base class. But I want to know where could and why would I want to use this style of object creation. Like in my last part of the example code;
BaseClass bc2 = new DerivedClass();
I can't reach derived class methods so I cant use derived class methods. But it is still derived class because of the new DerivedClass. If I use normal DerivedClass d = new DerivedClass(); style, I can use both class methods. I just cant find any reason and situation I would want to use this style. I would be glad if anyone show me in which situation I have to use derived class object from base class reference so I can understand this style is exist in language. I want to know WHY, I am not asking why this isn't working or something like that. Just want to know situations. Thank you.
There are two main usages:
1) Collections of multiple types
Lets change your example a little bit
public class Shape
{
public virtual void Display()
{
Console.WriteLine("I am a Shape");
}
public void BaseClassMethod()
{
Console.WriteLine("I am Base Class Method");
}
}
public class Square : Shape
{
public override void Display()
{
Console.WriteLine("I am Square");
}
public void DerivedClassMethod()
{
Console.WriteLine("I am Derived Class Method");
}
}
public class Circle : Shape
{
public override void Display()
{
Console.WriteLine("I am Circle");
}
}
class Program
{
static void Main(string[] args)
{
List<Shape> shapes = new List<Shape();
shapes.Add(new Square());
shapes.Add(new Circle());
I have a list that can hold Circles, Squares, and generic Shapes all in a single collection.
2) Polymorphism
Continuing on from the previous code
foreach(Shape shape in shapes)
{
shape.Display();
}
we don't know what kind of Shape the variable shape is, however we do know that whatever kind it is it will have a Display() method we can call and it will show the correct information.
Polymorphism is useful when you need to call a function on something but you don't know the specific type that something will be because you are pulling a collection of base types like above, or you want to write a function that can take in any kind of Shape because the function does not need to know the specific kind to do it's work.
public static void LogDisplay(Shape shape)
{
Console.WriteLine("I am about to call shape.Display()");
shape.Display();
Console.WriteLine("I am just called shape.Display()");
}
My favorite example, because people can understand the use, is logging. Imagine I create a website. When I'm developing the site, I want to log to my file system, because it's easy to access. When I deploy the website, I want to log to the event log, because maybe I don't have direct access to the file system on that machine.
However, I only want to change where things are logged, I want the base class to structure how the actual text looks. So I have my base class that formats text:
public abstract class BaseLogger
{
public abstract void LogException(Exception ex);
public abstract void LogUserMessage(string userMessage);
protected string GetStringFromException(Exception ex)
{
//....
}
protected string GetStringFromUserMessage(string userMessage)
{
//....
}
}
Now I can have a class that logs to the File System:
public class FileLogger : BaseLogger
{
public FileLogger(string filename)
{
//initialize the file, etc
}
public override void LogException(Exception ex)
{
var string = GetStringFromException(ex);
File.WriteAllLines(...);
}
public override void LogException(Exception ex)
{
var string = GetStringFromUserMessage(ex);
File.WriteAllLines(...);
}
}
and my class that logs to the Event Log:
public class EventLogger : BaseLogger
{
public EventLogger()
{
//initialize the eventlog, etc
}
public override void LogException(Exception ex)
{
var string = GetStringFromException(ex);
EventLog.WriteEntry(...);
}
public override void LogException(Exception ex)
{
var string = GetStringFromUserMessage(ex);
EventLog.WriteEntry(...);
}
}
Now in my program, I only care that I have a BaseLogger when I inject one into my classes. The implementation details are irrelevant, I just know that I can LogException and LogUserMessage no matter what I'm using.
When I'm using the logger I benefit from not caring which derived class I use. That's the benefit of treating each derived class like a base class. I can swap them out without my program caring.
There are many reasons to do this, mostly to do with code re-usability and extensiblity, which in other words, to make a small change or enhancement easily without needing to rewrite a whole lot.
A real world example (which happens frequently) is the case where you have different customers using your software which may require you to support different databases (or even different table structures). So in order to do that, you can derive implementations from a common base class, and vary in the implementation details without affecting the rest of the program.
This also follows the design principle "Program
to an 'interface', not an 'implementation'" which is explained in the GoF design pattern book
public abstract class ProviderBase
{
public abstract Employee[] GetAllEmployees();
}
public class MySqlProvider:ProviderBase
{
public override Employee[] GetAllEmployees()
{
string select = "select * from employees";
//query from mysql ...
}
}
public class MsSqlProvider : ProviderBase
{
public override Employee[] GetAllEmployees()
{
string select = "select * from user u left join employee_record e on u.id=e.id";
//query from mysql ...
}
}
Then in the main program you may be able to change the type of database implementation by configuration or Dependency Injection
ProviderBase provider = null;
if(databaseType == "MySql")
{
provider = new MySqlProvider();
}
else if (databaseType == "MsSql")
{
provider = new MsSqlProvider();
}
var employees = provider.GetAllEmployees();
//do something
I believe a lot of the reasoning behind the availability of using derived classes has to do with minimizing repeated code.
To reference a real life example...
If I was to ask you to describe the attributes and abilities of a car, and then was to ask you to do the same for an electric car, you would find that much of the attributes and abilities are shared by both. So instead of having it be two completely separate classes, it would be more efficient to create the base class Car, and derive electricCar from that. Then you will only need to account for the specific differences of the electric car within the derived class, and all the shared attributes and abilities will carry over.
Hope this helps you understand the usefulness of base classes and derived classes. Very oversimplified but I feel it may help you grasp the concept!
The main reason to use a base class is reusability and polymorphism
So you could create the class depending on a condition:
BaseClass bc
if(case1)
bc = new DerivedClass1();
else
bc = new DerivedClass2();
In the following application you can use bc even if you don't know what kind of derived class it is at compile time. You can pass it e.g. to other functions and call the overridden methode:
bc.Display();
Derived class methods can only be used when you know what kind of derived class you actual have. Then you can do a conversion.
DerivedClass1 dc = bc as DerivedClass1;
dc.DerivedClassMethod()

How can I ensure that a class has just 1 constructor in .NET?

Well my question is pretty self-explanatory. I have a class and I want to ensure that there is just 1 public constructor to this class. Moreover, I also want to ensure that the constuctor should have just 1 parameter. My class will be modified by many different developers, and I am looking for a way to ensure that they do not write any more constructors than are currently specified. Is it possible? If yes, then how?
Note, my class inherits from another class which currently does not have any constructor but it might have in the future. I don't know if this information will affect the answer or not but just thought of adding it.
Please help!
Thanks in advance!
You could consider writing a unit test to encode this design constraint. As long as the test isn't fiddled with, this will warn when the contraint is broken.
This would be a good case for a nice comment in your class detailing this constraint.
The following testing approach can be expanded to provide a test which could test derived types, rather than a single type. This approach is a type of static analysis, and removes the overhead that would be incurred by expensive runtime checking through reflection for instance. A test ensures that the design constraint is validated at build time, rather than at runtime which could be after code is released.
[Test]
public void myClass_must_have_one_single_paramter_ctor()
{
Type type = typeof(MyClass);
const BindingFlags Flags = (BindingFlags.Public | BindingFlags.Instance);
ConstructorInfo[] ctors = type.GetConstructors(Flags);
Assert.AreEqual(1, ctors.Length, "Ctor count.");
ParameterInfo[] args = ctors[0].GetParameters();
Assert.AreEqual(1, args.Length, "Ctor parameter count.");
Assert.AreEqual(typeof(string), args[0].ParameterType, "Ctor parameter type.");
}
public class MyClass
{
public MyClass(string woo) {}
}
All classes have one constructor. If you don't specify one in the source code, the compiler will add an empty public constructor - the equivalent of:
public class MyClass
{
public MyClass()
{
}
}
However if you specify at least one constructor in the source, only the constructors that you explicitly specify will be created, e.g. the following class has one public constructor that takes a single string parameter:
public class MyClass
{
public MyClass(string myParameter)
{
...
}
}
In short, there's nothing special you need to do. If you only want one public constructor then ... just write one public constructor.
Only the person who codes the class can restrict the number and type of constructors.
So if that is you, then you can just code it the way you want.
This could be achieved using reflection. The only thing you need to take care is, the base class code shouldn't be accessible to or editable by developers.
class Program
{
static void Main(string[] args)
{
Inherited obj = new Inherited("Alpha");
obj.test();
Inherited1 obj1 = new Inherited1(); //This will fail as there is no ctor with single param.
obj1.test();
}
}
public class MyBase
{
private static IList<string> ValidatedClasses = new List<string>();
public MyBase()
{
if(!ValidatedClasses.Contains(this.GetType().FullName) &&
!ValidateConstructorLogic())
{
throw new ApplicationException("Expected consturctor with single argument");
}
}
public bool ValidateConstructorLogic()
{
bool ValidConstFound = false;
foreach (var info in this.GetType().GetConstructors())
{
if(info.GetParameters().Length ==1)
{
lock (ValidatedClasses)
{
ValidatedClasses.Add(this.GetType().FullName);
}
ValidConstFound = true;
}
}
return ValidConstFound;
}
}
public class Inherited:MyBase
{
public Inherited(string test)
{
Console.WriteLine("Ctor");
}
public void test()
{
Console.WriteLine("TEST called");
}
}
public class Inherited1 : MyBase
{
public void test()
{
Console.WriteLine("TEST called");
}
}
You could use FxCop to validate your code against a set of predefined rules. I beleive this might be the apt solution to your problem. If you need help on creating custom FxCop rules, please refer this article.
Constructors are not inherited from base classes.
Your class will have only the constructors that you write, except for (as others have pointed out) a default public constructor that is generated by the compiler when you do not explicitly provide one of your own.
You could try using a nested builder, as described by Jon Skeet. Basically: You force the user to go through the builder which then calls the private class constructor. Since the class constructor is private, only the nested builder has access to it.
Alternative: Use static factory methods, make the constructor private & document your intentions.
Based on your comments, I don't think this is a "coding" problem. This is a policy & enforcement problem. You don't want other developers in your team creating more constructors.
In that case, go tell them that. Whoever is in charge of your source code repository can enforce it by rejecting changes that break the policy. Adding code to deal with this is just going to add runtime penalties to users for no reason.

Why cast to an interface?

In Jesse Liberty's Programming C# (p.142) he provides an example where he casts an object to an interface.
interface IStorable
{
...
}
public class Document : IStorable
{
...
}
...
IStorable isDoc = (IStorable) doc;
...
What is the point of this, particularly if the object's class implements the inteface anyway?
EDIT1: To clarify, I'm interested in the reason for the cast (if any), not the reason for implementing interfaces. Also, the book is his 2001 First Edition (based on C#1 so the example may not be germane for later versions of C#).
EDIT2: I added some context to the code
Because you want to restrict yourself to only methods provided by the interface. If you use the class, you run the risk of calling a method (inadvertently) that's not part of the interface.
There is only one reason when you actually need a cast: When doc is of a base type of an actual object that implements IStorable. Let me explain:
public class DocBase
{
public virtual void DoSomething()
{
}
}
public class Document : DocBase, IStorable
{
public override void DoSomething()
{
// Some implementation
base.DoSomething();
}
#region IStorable Members
public void Store()
{
// Implement this one aswell..
throw new NotImplementedException();
}
#endregion
}
public class Program
{
static void Main()
{
DocBase doc = new Document();
// Now you will need a cast to reach IStorable members
IStorable storable = (IStorable)doc;
}
}
public interface IStorable
{
void Store();
}
If the object implements the interface explicitly (public void IStorable.StoreThis(...)) that casting is the easiest way to actually reach the interface members.
I am not sure under what context the example was given in the book. But, you generally can type cast an object to interface to achieve multiple inheritance. I have given the example below.
public interface IFoo
{
void Display();
}
public interface IBar
{
void Display();
}
public class MyClass : IFoo, IBar
{
void IBar.Display()
{
Console.WriteLine("IBar implementation");
}
void IFoo.Display()
{
Console.WriteLine("IFoo implementation");
}
}
public static void Main()
{
MyClass c = new MyClass();
IBar b = c as IBar;
IFoo f = c as IFoo;
b.Display();
f.Display();
Console.ReadLine();
}
This would display
IBar implementation
IFoo implementation
It's pretty hard to tell without more of the context. If the variable doc is declared to be a type which implements the interface, then the cast is redundant.
Which version of the book are you reading? If it's "Programming C# 3.0" I'll have a look tonight when I'm at home.
EDIT: As we've seen in the answers so far, there are three potential questions here:
Why cast in the statement shown in the question? (Answer: you don't have to if doc is of an appropriate compile-time type)
Why is it ever appropriate to explicitly cast to an implemented interface or base class? (Answer: explicit interface implementation as shown in another answer, and also for the sake of picking a less specific overload when passing the cast value as an argument.)
Why use the interface at all? (Answer: working with the interface type means you're less susceptible to changes in the concrete type later on.)
The doc object might be of a type that implements members of IStorable explicitly, not adding them to the classes primary interface (i.e., they can only be called via the interface).
Actually "casting" (using the (T) syntax) does not make any sense since C# handles upcasts (cast to parent type) automatically (unlike F# for instance).
There are a lot of good answers here, but I don't really think they answer WHY you actually WANT to use the most restrictive interface possible.
The reasons do not involve your initial coding, they involve the next time you visit or refactor the code--or when someone else does it.
Let's say you want a button and are placing it on your screen. You are getting the button either passed in or from another function, like this:
Button x=otherObject.getVisibleThingy();
frame.add(x);
You happen to know that VisibleThingy is a button, it returns a button, so everything is cool here (no cast required).
Now, lets say that you refactor VisibleThingy to return a toggle button instead. You now have to refactor your method because you knew too much about the implementation.
Since you only NEED the methods in Component (a parent of both button and Toggle, which could have been an interface--same thing pretty much for our purposes), if you had written that first line like this:
Component x=(Component)otherObject.getVisibleThingy();
You wouldn't have had to refactor anything--it would have just worked.
This is a very simple case, but it can be much more complex.
So I guess the summary would be that an interface is a specific way to "View" your object--like looking at it through a filter...you can only see some parts. If you can restrict your view enough, the object can "Morph" behind your particular view and not effect anything in your current world--a very powerful trick of abstraction.
The best reason why you would cast to interfaces would be if you are writing code against objects and you don't know what concrete type they are and you don't want to.
If you know that you might come across an object that implements a specific interface you could then get the values out of the object without having to know the concrete class that this object is. Also, if you know that an object implements a given interface, that interface might define methods that you can execute to take certain actions on the object.
Here's a simple example:
public interface IText
{
string Text { get; }
}
public interface ISuperDooper
{
string WhyAmISuperDooper { get; }
}
public class Control
{
public int ID { get; set; }
}
public class TextControl : Control, IText
{
public string Text { get; set; }
}
public class AnotherTextControl : Control, IText
{
public string Text { get; set; }
}
public class SuperDooperControl : Control, ISuperDooper
{
public string WhyAmISuperDooper { get; set; }
}
public class TestProgram
{
static void Main(string[] args)
{
List<Control> controls = new List<Control>
{
new TextControl
{
ID = 1,
Text = "I'm a text control"
},
new AnotherTextControl
{
ID = 2,
Text = "I'm another text control"
},
new SuperDooperControl
{
ID = 3,
WhyAmISuperDooper = "Just Because"
}
};
DoSomething(controls);
}
static void DoSomething(List<Control> controls)
{
foreach(Control control in controls)
{
// write out the ID of the control
Console.WriteLine("ID: {0}", control.ID);
// if this control is a Text control, get the text value from it.
if (control is IText)
Console.WriteLine("Text: {0}", ((IText)control).Text);
// if this control is a SuperDooperControl control, get why
if (control is ISuperDooper)
Console.WriteLine("Text: {0}",
((ISuperDooper)control).WhyAmISuperDooper);
}
}
}
running this little program would give you the following output:
ID: 1
Text: I'm a text control
ID: 2
Text: I'm another text control
ID: 3
Text: Just Because
Notice that I didn't have to write any code in the DoSomething method that required me to know anything about all the objects I was working on being concrete object types. The only thing that I know is that I'm working on objects that are at least an instance of the Control class. I can then use the interface to find out what else they might have.
There's a million different reasons that you would take this approach with interfaces on your objects but it gives you a loose way to access your objects without having to know exactly what it is.
Think of all the credit cards in the world, every company makes their own, the interface is the same though, so every card reader can have a card swiped through it that follows the standard. Similar to the usage of interfaces.
As has been noted, the casting is superfluous and not necessary. However, it is a more explicit form of coding which would be useful to beginners in aiding their understanding.
In an introductory textbook, it is best to explicitly act, rather than let the compliler do things implicitly, which would be more confusing for beginners.
The "doc" is not of type "IStorable" so it would be confusing for beginners to see that it is being assigned to a isDoc. By explicitly casting, the author (of the book and of the code) is saying that a document can be casted to an IStorable object, but it is NOT THE SAME as an IStorable object.
The point is, the object (where did you get it?) may not implement the interface, in which case an exception is thrown which can be caught and dealt with. Of course you can use the "is" operator to check, and the "as" operator to cast instead of the C-style cast.
To allow for the most decoupling between pieces of code...
See the following article for more:
Interfaces
The main reason you would explicitly cast to an interface is if the members of the interface are implemented explicitly (i.e. with fully-qualified names in the form of InterfaceName.InterfaceMemberName). This is because when you fully-qualify them with the interface name, those members are not actually part of the implementing class's API. You can only get to them via casting to the interface.
Here's an example you can run as-is:
using System;
public interface ISomethingDoer {
void DoSomething();
}
public class ThingA : ISomethingDoer {
public void DoSomething(){
Console.WriteLine("ThingA did it!");
}
}
public class ThingB : ISomethingDoer {
// This is implemented explicitly by fully-qualifying it with the interface name
// Note no 'scope' here (e.g. public, etc.)
void ISomethingDoer.DoSomething(){
Console.WriteLine("ThingB did it!");
}
}
public static class Runner {
public static void Main(){
var a = new ThingA();
a.DoSomething(); // Prints 'ThingA did it!'
var b = new ThingB();
b.DoSomething(); // NOTE: THIS WILL NOT COMPILE!!!
var bSomethingDoer = (ISomethingDoer)b;
bSomethingDoer.DoSomething(); // Prints 'ThingB did it!'
}
}
HTH!

Categories

Resources