3

For example,I have a base class like this:

class Base: ICloneable
{
    public object Clone()
    {
      //something
    }
}

And is there any difference between these Derived classes?

class Derived: Base, ICloneable
{
    //something
}
class Derived: Base
{
    //something
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
shadowfish
  • 109
  • 4
  • No, there is no need to include the interface twice. Base class could implement dozens of interfaces. – vgru Nov 27 '19 at 14:20
  • 1
    Related: https://stackoverflow.com/questions/13516264/can-a-child-class-implement-the-same-interface-as-its-parent –  Nov 27 '19 at 14:22
  • 1
    As an aside, please make sure your sample code is actually valid, and ideally follows .NET naming conventions. You can't call a class `base` like that because it's a keyword. – Jon Skeet Nov 27 '19 at 14:24

5 Answers5

3

Actually, you can do this, if your derived class provides its own (explicit) implementation of the interface:

class B : A, Icloneable
{
    object IClonable.Clone()
    {
        // do something completely new
    }
}

As this is an explicit implementation, you have to cast your B-instance to the interface in order to call the new implementation. Otherwise the implementation from A is used (see my fiddle: https://dotnetfiddle.net/tuUnCm).

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
3

Well, you may need to do it; here is a possible scenario:

When cloning, we usually want to return not universal object by cloned object type:

class Base {
  // We can't declare this method as virtual: Derived class will return Derived 
  public Base Clone() {
    ...
  }
}

...

Base test = new Base();

Base duplicate = test.Clone(); 

If we want to implement IClonable we have to do it explictly (in order to solve Clone() names conflict):

class Base : ICloneable {
  public Base Clone() {
    ... 
  }

  // This method is efficiently private, and that's why can't be virtual
  object ICloneable.Clone() => Clone();
}

Now we want a Derived class which can be cloned as well:

class Derived : Base {
  // Note that now we have new Clone method which returns Derived instance (not Base one)
  public new Derived Clone() {
    ...
  }
}

...

Derived test = new Derived();

Derived duplicate = test.Clone();

If we keep it like this then we'll have wrong behaviour:

 Derived test = new Derived();

 // This will be wrong: 
 // Base.ICloneable.Clone() will be called which executes "Base Clone()" method
 // instead of expected "new Derived Clone()"
 object clone = (test as IClonable).Clone();

So we have to reimplement IClonable interface:

class Derived : Base, ICloneable {
  // Please, note that now we have new Clone method which returns Derived instance
  public new Derived Clone() {
    ...
  }

  // This ICloneable implementation will call Derived Clone()
  object ICloneable.Clone() => Clone();
}

...

// Derived ICloneable.Clone() will be called
// which executes "new Derived Clone()" method
object clone = (test as IClonable).Clone();
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

No, you do not have to implement the interface in the derived class. The derived class can also be cast as the interface type when the base class implements the interface. Like this:

public interface ISomething
{
    void Say();
}

public abstract class BaseClass : ISomething
{
    public void Say(string something)
    {
        Console.WriteLine("Say: " + something);
    }
}

public class DerivedClass : BaseClass
{
}

var x = new DerivedClass() as ISomething;
x.Say("Derived");
Matt U
  • 4,970
  • 9
  • 28
1

If understanding the problem correctly, you don't need to inherit for base and ICloneable as base already inherits from it.

This is fine

class base:ICloneable
{
    public object Clone()
    {
      //something
    }
}

This is fine too, as derived1 will inherit ICloneable, as its part of your base class

class derived1:base
{
    //something
}

However this is saying it will, inherit from base (which already inherits from ICloneable) AND ICloneable. Its redundant and defeats the purpose of having an interface.

class derived1:base,Icloneable
{
    //something
}

Hope that helps!

dros
  • 1,217
  • 2
  • 15
  • 31
0

No need, when your base class is implementing interface or other classes all the properties and functionality introduced in base class will inherit to derived class.