Beginner interface question

M

^MisterJingo^

I've been reading up on interfaces, one example I came across showed
that you can hide a method implemented from an interface from the class
which implements it. To use it, you must cast to the interface type
e.g.:

interface IFoo
{
void display();
}

class Blah : IFoo
{
void IFoo.display()
{
System.Console.WriteLine("hello");
}
}

class MainApp
{
public static void Main()
{
Blah myBlah = new Blah();

myBlah.display(); //error
((IFoo)myBlah).display(); //works
}
}

In what circumstances would you ever want to do this? The place I found
this didn't explain why this would ever be done.
Sorry if these questions are missing the obvious :).

Chris
 
Y

yoshijg

The circumstances you would use an Interface in such a manner, is when
there is a need to limit accessibility to methods.

For example, suppose your "Blah" class was an abstraction of a
Database. Inside that class would be "Delete", "Create", "Update",
"Insert", "Select" functions. Now whoever uses the "Blah" object can
do some serious damage to the Database if they are not careful. So to
limit damage you might want to create an interface. Possible
interfaces would be as follows :

IDbAdmin -> Has access to all functions
IReadOnlyUser -> Has access to "Select" functions only.
IUpdateOnlyUser -> Has access to "Update" / "Insert" functions only.
ICreateOnlyUser -> Has access to "Create" functions only.
etc..

You can also chose to not create a "Delete" interface because you may
decide only admins have access to that feature.

I believe this is what they call a FACADE pattern.

Hope this was a good practical example.

enjoy,
Josh Go
 
D

Dave Johnson

I have the same Problem, and cannt figure it out as i am new to
Interfaces,

Classes:

1-DataRepository Class - Contains (GetClientInfo Method, GetOrderInfo
Method)
2-Client Class
3-Order Class

The DataRepository Class has all the Functions that deals with the
Database such as (Client & Order) database methods.

Required:

make the Client Class have only Access to the GetClientInfo Method
and not also the GetOrderInfo Method and vice versa

How to do it using Interfaces??

can u please show it in code, as i am new to Interfaces



Sharing makes All the Difference
 
Y

yoshijg

Hey Dave,

I replied to your original post about FACADEs.

Here is some sample code. In this example I create a "TextFile" object
which is an abstraction of a normal text file on disk. Now every file
on your computer has "Access" rights. I simulated those access rights
with interfaces. So in this example, there is a "IReadOnlyUser",
"IWriteOnlyUser", and "IFileAdmin" interface. The first 2 interfaces
are pretty self-explanatory and the IFileAdmin is just an interface
that has both read/write capabilities.

using System;

namespace CS_InterfaceTest
{
#region interfaces

interface IFileAdmin : IReadOnlyUser, IWriteOnlyUser{}

interface IReadOnlyUser
{
void PrepareForRead();
string ReadLine();
void CloseRead();
}


interface IWriteOnlyUser
{
void PrepareForWrite();
void WriteLine(string p_String);
void CloseWrite();
}

#endregion

#region textfile class

class TextFile : IFileAdmin
{
private string m_Filename;
private System.IO.StreamReader m_StreamReader;
private System.IO.StreamWriter m_StreamWriter;

#region properties

public string Filename
{
get{return m_Filename;}
set{m_Filename = value;}
}

#endregion

#region read access

void IReadOnlyUser.PrepareForRead()
{
m_StreamReader = new System.IO.StreamReader(this.Filename);
}


string IReadOnlyUser.ReadLine()
{
string buff = null;
if( m_StreamReader.Peek() != -1 )
{
buff = m_StreamReader.ReadLine();
}
return buff;
}


void IReadOnlyUser.CloseRead()
{
m_StreamReader.Close();
}

#endregion

#region write access
void IWriteOnlyUser.PrepareForWrite()
{
m_StreamWriter = new System.IO.StreamWriter(this.Filename,
true);
}


void IWriteOnlyUser.WriteLine(string p_String)
{
m_StreamWriter.WriteLine(p_String);
}


void IWriteOnlyUser.CloseWrite()
{
m_StreamWriter.Close();
}
#endregion

}

#endregion

#region main/testing code
class MainClass
{
[STAThread()]
public static void Main()
{
TextFile file = new TextFile();
file.Filename = "foo.txt";

Console.WriteLine("---- Admin Test ----");
FullyTrustedUser((IFileAdmin)file);

Console.WriteLine("");

Console.WriteLine("---- Write Test ----");
SemiTrustedUser((IWriteOnlyUser)file);

Console.WriteLine("");

Console.WriteLine("---- Read Test ----");
UntrustedUser((IReadOnlyUser)file);
}

//demonstrate read/write access
public static void FullyTrustedUser(IFileAdmin p_Admin)
{
//Write something
p_Admin.PrepareForWrite();
p_Admin.WriteLine("I am the admin");
p_Admin.CloseWrite();

//Read it out
p_Admin.PrepareForRead();
string buff = p_Admin.ReadLine();

while( buff != null)
{
Console.WriteLine(buff);
buff = p_Admin.ReadLine();
};
p_Admin.CloseRead();
}

//demonstrate read access
public static void UntrustedUser(IReadOnlyUser p_Read)
{
p_Read.PrepareForRead();
string buff = p_Read.ReadLine();

while( buff != null)
{
Console.WriteLine(buff);
buff = p_Read.ReadLine();
};
p_Read.CloseRead();
}

//demonstrate write access
public static void SemiTrustedUser(IWriteOnlyUser p_Write)
{
p_Write.PrepareForWrite();
p_Write.WriteLine("I am not fully trusted");
p_Write.CloseWrite();
}
}
#endregion
}
 
J

Jeff Louie

yoshig... one caution, limiting access through the type of a reference
is a weak guarantee. once I have access to the reference of the limited
type, I can just cast it to the type of the full reference.

Regards,
Jeff
 
J

Jeff Louie

How about:

using System;
using System.Collections.Generic;
using System.Text;

namespace LimitedAccess
{
interface IData
{
int ClientInfo { get;set;}
int OrderInfo { get;set;}
}
interface IClient
{
int ClientInfo { get;}
}
interface IAdministrator
{
int ClientInfo { get;set;}
int OrderInfo { get;set;}
}
// not thread safe
class Data : IData
{
private int clientInfo = 0;
private int orderInfo = 0;
public Data(int clientInfo, int orderInfo) {
this.clientInfo= clientInfo;
this.orderInfo= orderInfo;
}
public int ClientInfo
{
get { return this.clientInfo; }
set { this.clientInfo = value; }
}
public int OrderInfo
{
get { return this.orderInfo; }
set { this.orderInfo = value; }
}
}
class Client : IClient
{
private IData data = null;
//ASSERT data not null
public Client(IData data)
{
if (data == null) { throw new ArgumentException(); }
this.data = (Data)data;
}
public int ClientInfo
{
get { return data.ClientInfo; }
}
class Administrator : IAdministrator
{
private IData data = null;
// ASSERT data not null
public Administrator(IData data)
{
if (data == null) { throw new ArgumentException(); }
this.data = data;
}
public int ClientInfo
{
get
{
return data.ClientInfo;
}
set
{
this.data.ClientInfo = value;
}
}
public int OrderInfo
{
get { return this.data.OrderInfo; }
set { this.data.OrderInfo = value; }
}

static void Main(string[] args)
{
IData data= new Data(2,3);
Administrator adm = new Administrator(data);
Client c = new Client(data);
System.Console.WriteLine(adm.OrderInfo);
System.Console.WriteLine(c.ClientInfo);
//System.Console.WriteLine(c.OrderInfo); // error Client
does not contain a definition...
System.Console.ReadLine();
}
}
}
}


Regards,
Jeff
 
Y

yoshijg

Hey Jeff,

You are totally correct and thanks for pointing that out. Interfaces
are not the way to go for "securing access". I should have picked a
better example than "read/write access"...sorry about that.
The idea behind my solution was to be able to relate a bunch of
functions, but still deal with the exact same object.

I actually like your example, it's very clear and assertive. The data
and logic are completely broken as they should be.

Now as for Dave Johnson's request...the 2nd post. What's your take on
that?
 
J

Jeff Louie

Hmm... A correction:

private IData data = null;
//ASSERT data not null
public Client(IData data)
{
if (data == null) { throw new ArgumentException(); }
this.data = data; // no need to cast to (Data)
}

So you can pass any concrete class that implements IData.

Regards,
Jeff
 
G

Guest

Here's how I would use explicit interface implementation

1. the obvious one is to avoid method collision. when two interfaces have
the same method defined, but will require different implementations.
although I don't remember ever run into this situation.
2. if the member should be exposed using an alternative name better suited
in the context of the object that implements it. I'd hide the interface name
instead of exposing both.
3. if a method is rarely / never called directly off of the object, most
times it's something required for the framework support and used indirectly
by something else. IComparable.CompareTo is always a good candidate for that.
4. related to 3, when implementing an internal interface. typically, these
should always be hidden from the consumers.
 
M

^MisterJingo^

Thanks for the replies all, it makes more sense now. I thought it might
be a bit 'fiddly' casting to the interface type to call certain
methods, but after playing around, I found out this:

public interface IShape
{
double area();
double circumference();
int sides();
void blah();
}

public class Oblong :IShape
{
public int side;

public double area() { return (double)((side * side) * 2); }

public double circumference() { return ((double)(6 * side)); }

public int sides() { return 4; }
public Oblong() { side = 0;}

void IShape.blah(){ Console.WriteLine("Test"); }
}

public class Shape
{
public static void Main(string[] args)
{
Oblong myOb = new Oblong();
myOb.side = 5;
Console.WriteLine("Displaying Info:");
displayInfo(myOb);
}

static void displayInfo(IShape myShape)
{
Console.WriteLine("Area: {0}", myShape.area());
Console.WriteLine("Sides: {0}", myShape.sides());
Console.WriteLine("Circumference: {0}",
myShape.circumference());
myShape.blah();
}
}

using a method taking the interface type, I can perhaps see uses for
that.

A quick question:
If I had a number of objects which were not derived from the same base
class. Each of these objects had a load and save method, which were
called on every instanced object when the user selected a save event.
Would it be best to create a load/save interface, and then use a method
such as above. Or would it be best to use a function which calls every
object in turn, decides what form the object is and then load/save. Or
even factoring all objects which need load and save functionality into
a common base class? (the load or save could be something like
drawToScreen etc).

I'm trying to get my head around when best to use interfaces etc.

Thanks,

Chris
 
J

Jeff Louie

MJ... If each object has special features then you might want to
implement a
persistance interface and each object would provide a custom behavior at
Save.
If most objects can be persisted using generic logic then you can rely
on generic
persistance. So most object persist using [Serializable] just fine, a
few do not
and need to also implement ISerializable such as Singleton classes,
providing a
custom behavior.

Regards,
Jeff
If I had a number of objects which were not derived from the same base
class. Each of these objects had a load and save method, which were
called on every instanced object when the user selected a save event.
Would it be best to create a load/save interface, and then use a method
such as above. Or would it be best to use a function which calls every
object in turn, decides what form the object is and then load/save. Or
even factoring all objects which need load and save functionality into
a common base class? (the load or save could be something like
drawToScreen etc).<
 
J

Jeff Louie

_Internal_ to a project, you may come to the day that you define the
contract
first for almost everything and then start building concrete classes. So
you
program to a contract, contract first, using Interfaces. Internal to a
project, you
will be amazed at how this helps. Say you need to add a new method to an
Interface. Just do it and the compiler flags every concrete class that
needs to be
updated.

Regards,
Jeff
 
D

Dave Johnson

hello josh, first of all thanks for your reply, thank you all guys it
has been great to witness all these action and try to learn from it.
the following code works for me, i only have access to the properties
and methods that i want, but i am not quite sure that i doing this
right, i mean it could have been done without interfaces in the
following code and it would have worked, so appearntly i didnt quite get
it and as this newsgroups are my only source of learning so far i would
appreciate feedbacks and comments as much as possilbe, whatz the trick
??!!

interface IData
{
int ClientInfo { get;set;}
int OrderInfo { get;set;}
}
interface IClient
{
int ClientInfo { get;}
}
interface IAdministrator
{
int ClientInfo { get;set;}
int OrderInfo { get;set;}
}



class Data : IData
{
private int clientInfo = 0;
private int orderInfo = 0;
public Data()
{
this.clientInfo= clientInfo;
this.orderInfo= orderInfo;
}
public int ClientInfo
{
get { return this.clientInfo; }
set { this.clientInfo = value; }
}
public int OrderInfo
{
get { return this.orderInfo; }
set { this.orderInfo = value; }
}
}

class Client : IClient
{
Data data = new Data();

public Client()
{
this.data = data;
}
public int ClientInfo
{
get { return data.ClientInfo; }
}
}

namespace WebApplication12
{

class Administrator : IAdministrator
{
private IData data = null;
public Administrator()
{

this.data = data;
}
public int ClientInfo
{
get
{
return data.ClientInfo;
}
set
{
this.data.ClientInfo = value;
}
}
public int OrderInfo
{
get { return this.data.OrderInfo; }
set { this.data.OrderInfo = value; }
}
}


Sharing makes All the Difference
 
J

Jeff Louie

Dave... You are right. Except for IData you could have solved this
problem
without an interface. The key concepts are
1) using containment by reference to adapt the readwrite IData interface
to a
limited IClient interface and
2) understanding that multiple objects can hold a reference to a single
object
without the need for reference counting.

Since Client and Administrator take IData as a parameter, you can pass a
different Data class in the future and the code will still work. In fact
you can
pass any class that implements IData to the constructors and it will
work in
the future.

If you don't find the ability to look at the public contract as:

interface IData
{
int ClientInfo { get;set;}
int OrderInfo { get;set;}
}
interface IClient
{
int ClientInfo { get;}
}
interface IAdministrator
{
int ClientInfo { get;set;}
int OrderInfo { get;set;}
}

helpful, then there is no need to abstract out all of the interfaces. At
least
until you write a gazillion concrete classes and then decide to modify a
single
contract. If you used interfaces, the compiler will find all of the
concrete
classes that need to be updated!

There are at least four times when interfaces or abstract base classes
are
useful:

Polymorphic behavior
Defering the final behavior to a more knowledgable class
Encapsulating or hiding the implementation
Marking a class

So try to write some code that uses these four idioms and you will see
the
light. If you need hints:

IDrawable
IComparable
IPlugIn
IRequiresSessionState

Regards,
Jeff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top