Implementing interface problem

G

Guest

Hi

I make a class "MyClass" and this clas implements the Interface ICloneable.
I want when I instance an object from MyClass and I call obj.Clone() it
returns an object of MyClass type.

for example:
public class MyClasss : ICloneable
{
public void A();
public object Clone(){} // The ICloneable Method
}

when I do this:
MyClass obj;
obj.Clone() I want also call the method A. but Clone returns an object, not
a MyClass object. If I defines the Clone method like this: public MyClass
Clone{} I receive an error, It is logic. but all .NET classes that implements
the interface ICloneable, the method Clone returns an object of the same type
of the class that implement this interface.

how can I do this!

thanks
 
B

Bob Powell [MVP]

Just cast the object returned by IClonable to your type.

MyClass x=new MyClass();
MyClass y=(MyClass)x.Clone();

y holds a copy of x.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
R

Richard Blewett [DevelopMentor]

Clone returns to a MyClass object by via an oject reference. The type of the allocated object is still MyClass so all you need to do is cast the result

MyClass obj = new MyClass();
MyClass copy = (MyClass)obj.Clone();
copy.A();

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Hi

I make a class "MyClass" and this clas implements the Interface ICloneable.
I want when I instance an object from MyClass and I call obj.Clone() it
returns an object of MyClass type.

for example:
public class MyClasss : ICloneable
{
public void A();
public object Clone(){} // The ICloneable Method
}

when I do this:
MyClass obj;
obj.Clone() I want also call the method A. but Clone returns an object, not
a MyClass object. If I defines the Clone method like this: public MyClass
Clone{} I receive an error, It is logic. but all .NET classes that implements
the interface ICloneable, the method Clone returns an object of the same type
of the class that implement this interface.

how can I do this!

thanks
 
J

Jeff Louie

Hex.... So to summarize, Clone returns a reference variable of type
object to
an object on the heap of class MyClass. The type of the variable,
object,
restricts access to the object interface of MyClass. By casting to a
reference
variable of type MyClass, you are now explicitly saying that you want to
touch
the full public interface of MyClass with the new reference variable.

Please note that some Clone methods only return a shallow copy. For
example, if you clone an Array list, you get a copy of the list filled
with the
appropriate references. If the objects "pointed to" by the array list
are
mutable, you do not have exclusive control over the objects "pointed to"
by
the clone of the array list. This may _not_ be what you want. As best as
I can
tell, if you clone an ArrayList of strings, you are OK since strings are
immutable.

Regards,
Jeff
but Clone returns an object, not
a MyClass object.<
 
G

Guest

Hi Louie

I appreciate your answer, the example of the Clone method, just was this, an
example. Maybe I do not express very well, but I appreciate “again†your
answer.

What I want is that my class implements some interface, but one of the
methods defined in the interface, at the moment on the implementation,
returns another object type than the type defined in the interface. Like
System.Xml.XmlNode, this class implements ICloneable (for example), so it has
the Clone method, but this method does not returns an object as ICloneable
defines, this method returns a System.Xml.XmlNode, and when you clone a node,
you didn’t need a casts. That’s what I want.

You finish your reply exactly as I want, but inverse: “but Clone returns an
object, not a MyClass object.†I want MyClass.Clone() returns a MyClass and
at the same time MyClass implements ICloneable. Is like hide a member in an
inheritance but with interfaces:

In inheritance:
public class A
{
public void F(){}
}

public class B : A
{
new public int F(){} // this hides void F()
}

In interfaces:

public interface Iifc
{
void F();
}

public class a : Iifc
{
new int F(){} /* this not hides the method in the interface. And an error
was received here, but I want F() returns an new type different from the
defined in the interface, like System.Xml.XmlNode.Clone() returns a like
System.Xml.XmlNode and not an object as ICloneable defines.*/
}

I hope you understand me, if you know some way to do that, I appreciate it.
Thanks for your time.
Ed

Note: I apologize for the display name change.
 
J

Jeff Louie

Ed... Since an interface is a contract, the method _must_ return an
instance that implements the return type (or it may return null).

The trick is to understand that the interface method may be declared as
returning a common base type or interface, even object. If you declare
the interface as returning object, then the implementation can return
any instance that inherits from object.

Regards,
Jeff
I want F() returns an new type different from the
defined in the interface<

============== CODE ===================
using System;

namespace TestReturn
{
interface IPrint
{
void Identify();
}
class ClassOne : IPrint
{
public void Identify()
{
Console.WriteLine("One");
}
}
class ClassTwo : IPrint
{
public void Identify()
{
Console.WriteLine("Two");
}
}
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
public enum ClassEnum{one,two};

static object GetInstance(ClassEnum e)
{
switch (e)
{
case ClassEnum.one:
return new ClassOne();
case ClassEnum.two:
return new ClassTwo();
default:
return null;
}
}

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
object o= Class1.GetInstance(ClassEnum.one);
if (o is IPrint)
{
((IPrint)o).Identify();
}
System.Console.ReadLine();
}
}
}

============= END CODE ============

if you don't want to cast then return the interface:

============ MORE CODE =====================

class Class1
{
public enum ClassEnum{one,two};

static IPrint GetInstance(ClassEnum e)
{
switch (e)
{
case ClassEnum.one:
return new ClassOne();
case ClassEnum.two:
return new ClassTwo();
default:
return null;
}
}

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
IPrint ip= Class1.GetInstance(ClassEnum.two);
ip.Identify();
System.Console.ReadLine();
}
}
}

See Ya.
 
G

Guest

Thanks for your explication and code sample; I understand the interface
implementation process better now.

Thanks for your time
ed
 
K

Kurt

hex said:
Hi

I make a class "MyClass" and this clas implements the Interface ICloneable.
I want when I instance an object from MyClass and I call obj.Clone() it
returns an object of MyClass type.

for example:
public class MyClasss : ICloneable
{
public void A();
public object Clone(){} // The ICloneable Method
}

when I do this:
MyClass obj;
obj.Clone() I want also call the method A. but Clone returns an object, not
a MyClass object. If I defines the Clone method like this: public MyClass
Clone{} I receive an error, It is logic. but all .NET classes that implements
the interface ICloneable, the method Clone returns an object of the same type
of the class that implement this interface.

how can I do this!

thanks

public class Foo : ICloneable
{
public Foo Clone() { return CloneFoo(); }
object ICloneable.Clone() { return CloneFoo(); }
protected virtual Foo CloneFoo() { return new Foo(); }
}
For decendants of foo you need can use the new keyword on the method
to hide the base class method and return a different type. The new
method is only invoked when the caller is using the Foo2 interface as
opposed to Foo interface or clonable interface so normally the use of
the new keyword is strongly discurraged however in this case the
functionality is exactly the same only the signature is changed and
therefore is required.

public class Foo2 : Foo
{
protected override Foo CloneFoo() { return new Foo2(); }
public new Foo2 Clone() { return (Foo2)CloneFoo(); }
}

- Kurt
 
J

Jeff Louie

Or...

using System;

namespace TestICloneable
{
public class Class1 :ICloneable
{
public void ID() {Console.WriteLine("one");}
public virtual object Clone() { return CloneClass1(); }
private Class1 CloneClass1() { return new Class1(); }
}
public class Class2 : Class1
{
public void ID() {Console.WriteLine("two");}
private Class2 CloneClass2() { return new Class2(); }
public override object Clone() { return CloneClass2(); }
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
//
// TODO: Add code to start application here
//
Class2 c2= new Class2();
c2.ID(); //two
Class2 c3= (Class2)c2.Clone();
c3.ID(); //two
Class1 c1= (Class1)c2;
c1.ID(); //one
Class2 c4= (Class2)c1.Clone(); // polymorphism
c4.ID(); // two
ICloneable ic= (ICloneable)c2;
ic.Clone();
Console.ReadLine();
}
}

}

Regards,
Jeff
/*
public class Foo : ICloneable
{
public Foo Clone() { return CloneFoo(); }
object ICloneable.Clone() { return CloneFoo(); }
protected virtual Foo CloneFoo() { return new Foo(); }
}
For decendants of foo you need can use the new keyword on the method
to hide the base class method and return a different type. The new
method is only invoked when the caller is using the Foo2 interface as
opposed to Foo interface or clonable interface so normally the use of
the new keyword is strongly discurraged however in this case the
functionality is exactly the same only the signature is changed and
therefore is required.

public class Foo2 : Foo
{
protected override Foo CloneFoo() { return new Foo2(); }
public new Foo2 Clone() { return (Foo2)CloneFoo(); }
}
*/
 

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