所以我读到在.net 中不可能继承第二个基类。那么如何创建一个对象,为 2 个类提供 2 个功能?例如,我有一个我想成为工具和武器的对象。第一个是 public class SmithHammer : BaseTool 第二个看起来像 public class SmithHammer : BaseBashing 这两个类 BaseTool 和 BaseBashing 显然不能同时用于同一个项目。作为一种武器,我用这种方式编码以调用基类 BaseBashing。
{
[FlipableAttribute( 0x13E3, 0x13E4 )]
public class SmithyHammer : BaseBashing
{
public override string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
public override int OldStrengthReq { get { return 45; } }
public override int OldMinDamage { get { return 6; } }
public override int OldMaxDamage { get { return 18; } }
public override int OldSpeed { get { return 40; } }
public override int InitMinHits { get { return 31; } }
public override int InitMaxHits { get { return 60; } }
[Constructable]
public SmithyHammer()
: base(0x13E3)
{
Weight = 8.0;
Layer = Layer.OneHanded;
Name = "Smith Hammer";
}
public SmithyHammer(Serial serial)
: base(serial)
{ }
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
}
}
在第二次使用中,我将其作为工具
namespace Server.Items
{
[FlipableAttribute( 0x13E3, 0x13E4 )]
public class SmithHammer : BaseTool
{
public override CraftSystem CraftSystem{ get{ return DefBlacksmithy.CraftSystem; } }
[Constructable]
public SmithHammer() : base( 0x13E3 )
{
Weight = 8.0;
Layer = Layer.OneHanded;
}
[Constructable]
public SmithHammer( int uses ) : base( uses, 0x13E3 )
{
Weight = 8.0;
Layer = Layer.OneHanded;
}
public SmithHammer( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}
是不是不能让这个项目兼具这两个功能?
回答1
这种情况有一种机制 - https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/interfaces。 C# 中的类不支持多重继承,但支持实现多个接口。在这种情况下,您可以创建两个(甚至更多)代表所需合同(即接口)的接口:
public interface IBashing
{
string Damage { get; }
int OldStrengthReq { get; }
// ...
// rest of properties/methods for bashing/weapon
}
public interface ITool
{
CraftSystem CraftSystem { get; }
// ...
}
并在 Hammer
类中实现它们:
public class SmithHammer : IBashing, ITool
{
public string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
public int OldStrengthReq { get { return 45; } }
public CraftSystem CraftSystem { get{ return DefBlacksmithy.CraftSystem; } }
// rest of implemetations
}
客户端可以通过接口或使用https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast来使用这个锤子类实例。例如,如果您将 IItem
接口引入到 store 库存中的所有内容(即 interface IBashing : IItem
和 interface ITool : IItem
),它可能如下所示:
var inventory = new List<IItem>();
// add some items
// pick some i'th item:
var item = inventory[i];
var tool = item as ITool; // or use pattern matching here
if(tool != null)
{
// use tool
}
else
{
....
}
使用接口共享实现并不是那么容易(除非您可以并且想要使用https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces/),但可以通过组合和包装来实现,即:
public class SmithyHammerBashing : BaseBashing
{
public override string Damage { get { return WeaponControl.Settings.SmithyHammerDamage; } }
public override int OldStrengthReq { get { return 45; } }
}
public class SmithHammer : IBashing, ITool
{
private readonly SmithyHammerBashing Bashing = new SmithyHammerBashing(); // or construct some other way
public string Damage { get { return Bashing.Damage; } }
public int OldStrengthReq { get { return Bashing.OldStrengthReq; } }
// the same approach for ITool
}