Historia wymaga pasterzy, nie rzeźników.

WriteLine("Creating document with: {0}", s);

}

// implement IStorable
public void Read( )
{

page 124
Programming C#
Console.WriteLine(
"Implementing the Read Method for IStorable");
}

public void Write(object o)
{
Console.WriteLine(
"Implementing the Write Method for IStorable");
}

public int status
{
get
{
return dbStatus;
}

set
{
dbStatus = value;
}
}

// implement ICompressible
public void Compress( )
{
Console.WriteLine("Implementing Compress");
}

public void Decompress( )
{
Console.WriteLine("Implementing Decompress");
}

// implement ILoggedCompressible
public void LogSavedBytes( )
{
Console.WriteLine("Implementing LogSavedBytes");
}

// implement IStorableCompressible
public void LogOriginalSize( )
{
Console.WriteLine("Implementing LogOriginalSize");
}

// implement IEncryptable
public void Encrypt( )
{
Console.WriteLine("Implementing Encrypt");

}

public void Decrypt( )
{
Console.WriteLine("Implementing Decrypt");

}

// hold the data for IStorable's status property
private int dbStatus = 0;
}

public class Tester

page 125
Programming C#
{

static void Main( )
{
// create a document object
Document doc = new Document("Test Document");

// cast the document to the various interfaces
IStorable isDoc = doc as IStorable;
if (isDoc != null)
{
isDoc.Read( );
}
else
Console.WriteLine("IStorable not supported");

ICompressible icDoc = doc as ICompressible;
if (icDoc != null)
{
icDoc.Compress( );
}
else
Console.WriteLine("Compressible not supported");

ILoggedCompressible ilcDoc = doc as ILoggedCompressible;
if (ilcDoc != null)
{
ilcDoc.LogSavedBytes( );
ilcDoc.Compress( );
// ilcDoc.Read( );
}
else
Console.WriteLine("LoggedCompressible not supported");

IStorableCompressible isc = doc as IStorableCompressible;
if (isc != null)
{
isc.LogOriginalSize( ); // IStorableCompressible
isc.LogSavedBytes( ); // ILoggedCompressible
isc.Compress( ); // ICompressible
isc.Read( ); // IStorable

}
else
{
Console.WriteLine("StorableCompressible not supported");
}

IEncryptable ie = doc as IEncryptable;
if (ie != null)
{
ie.Encrypt( );
}
else
Console.WriteLine("Encryptable not supported");

}
}

Output:

Creating document with: Test Document
Implementing the Read Method for IStorable
Implementing Compress

page 126
Programming C#
Implementing LogSavedBytes
Implementing Compress
Implementing LogOriginalSize
Implementing LogSavedBytes
Implementing Compress
Implementing the Read Method for IStorable
Implementing Encrypt
Example 8-2 starts by implementing the IStorable interface and the ICompressible interface.
The latter is extended to ILoggedCompressible and then the two are combined into IStorableCompressible. Finally, the example adds a new interface, IEncryptable.
The Tester program creates a new Document object and then casts it to the various interfaces.
When the object is cast to ILoggedCompressible, you can use the interface to call methods on Icompressible because ILoggedCompressible extends (and thus subsumes) the methods from the base interface:
ILoggedCompressible ilcDoc = doc as ILoggedCompressible;
if (ilcDoc != null)
{
ilcDoc.LogSavedBytes( );
ilcDoc.Compress( );
// ilcDoc.Read( );
}
You cannot call Read( ), however, because that is a method of IStorable, an unrelated interface.
And if you uncomment out the call to Read( ), you will receive a compiler error.
If you cast to IStorableCompressible (which combines the extended interface with the Storable interface), you can then call methods of IStorableCompressible, Icompressible, and IStorable:
IStorableCompressible isc = doc as IStorableCompressible
if (isc != null)
{
isc.LogOriginalSize( ); // IStorableCompressible
isc.LogSavedBytes( ); // ILoggedCompressible
isc.Compress( ); // ICompressible
isc.Read( ); // IStorable
}

isc.LogOriginalSize( ); // IStorableCompressible
isc.LogSavedBytes( ); // ILoggedCompressible
isc.Compress( ); // ICompressible
isc.Read( ); // IStorable

8.2 Accessing Interface Methods
You can access the members of the IStorable interface as if they were members of the Document class:
Document doc = new Document("Test Document");
doc.status = -1;
doc.Read( );

page 127
Programming C#
or you can create an instance of the interface by casting the document to the interface type, and then use that interface to access the methods:
IStorable isDoc = (IStorable) doc;
isDoc.status = 0;
isDoc.Read( );
In this case, in Main( ) you know that Document is in fact an IStorable, so you can take advantage of that knowledge.
As stated earlier, you cannot instantiate an interface directly. That is, you cannot say:
IStorable isDoc = new IStorable( );
You can, however, create an instance of the implementing class, as in the
following:
Document doc = new Document("Test Document");
You can then create an instance of the interface by casting the implementing
object to the interface type, which in this case is IStorable:
IStorable isDoc = (IStorable) doc;
You can combine these steps by writing:
IStorable isDoc =
(IStorable) new Document("Test Document");