为了完全理解如何解决Java的多重继承问题,我有一个经典的问题需要澄清.
可以说我有类Animal此有子类Bird和Horse我需要做一个类Pegasus,从扩展Bird和Horse自Pegasus既是一只鸟和一匹马.
我认为这是经典的钻石问题.从我能理解经典的方式来解决,这是使Animal,Bird和Horse类接口,并实现Pegasus从他们.
我想知道是否有另一种方法来解决我仍然可以为鸟类和马创造物体的问题.如果有一种方法可以创造动物,那将是伟大的但不是必要的.
java oop multiple-inheritance diamond-problem multiple-interface-implem
我有一个对象树,我正在序列化为JSON DataContractJsonSerializer.Dictionary<TKey, TValue>得到序列化但我不喜欢标记 - 项目不会像这样呈现:
{key1:value, key2:value2}
Run Code Online (Sandbox Code Playgroud)
而是像一系列序列化KeyValuePair<TKey, TValue>对象:
[{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key1",
"value":"value1"
},
{
"__type":"KeyValuePairOfstringanyType:#System.Collections.Generic",
"key":"key2",
"value":"value2"
}]
Run Code Online (Sandbox Code Playgroud)
丑,不是吗?
因此,我通过将通用Dictionary包装在实现的自定义对象中来避免这种情况ISerializable,并且我在GetObjectData方法中实现了自定义序列化(并且它只需要3行).
现在的问题-我不能让我的类从派生Dictionary<TKey, TValue>,所以我实现所有的逻辑(Add,Clear,等),在我的自定义类,被应用到私人Dictionary<TKey, TValue>领域.继承会更好,因为在使用我的自定义对象时,我将拥有所有通用字典功能.
继承的问题是它自己的Dictionary<TKey, TValue>实现ISerializable,并且DataContractJsonSerializer似乎更喜欢这个实现,即使我ISerializable从我的自定义类显式实现,如下所示:
public class MyClass : Dictionary<string, object>, ISerializable
{
public override void GetObjectData(SerializationInfo info,
StreamingContext context)
}
Run Code Online (Sandbox Code Playgroud)
我真的很惊讶这是可能的,因为它允许我实现相同的接口两次而不显然能够使用显式接口实现 - 所以我在一篇关于多接口实现的博客文章中更详细地分析了这种情况
所以,根据我在那里做的实验,序列化器应该调用我的ISerializable实现,无论内部使用什么类型的转换 -
((ISerializable)((Dictionary<,>)obj)).GetObjectData(...)
Run Code Online (Sandbox Code Playgroud)
要么:
((ISerializable)obj).GetObjectData(...)
Run Code Online (Sandbox Code Playgroud)
但它显然没有发生,因为我在生成的JSON中看到KeyValuePair<TKey, TValue> …
.net oop serialization multiple-interface-implem datacontractjsonserializer
在内部,作者实现了一个暴露多个接口的类(IObjectWithSite,IDispatch).
他的QueryInterface函数执行以下操作:
if(riid == IID_IUnknown) *ppv = static_cast<BHO*>(this);
else if(riid == IID_IObjectWithSite) *ppv = static_cast<IObjectWithSite*>(this);
else if (riid == IID_IDispatch) *ppv = static_cast<IDispatch*>(this);
Run Code Online (Sandbox Code Playgroud)
我从C角度了解到,接口指针只是VTables的指针.所以我认为C++能够使用static_cast返回任何已实现接口的VTable.
这是否意味着以这种方式构造的类在内存中有一堆VTable(IObjectWithSite,IDispatch等)?C++对不同接口上的名称冲突做了什么(它们各自都有QueryInterface,AddRef和Release函数),我可以为每个接口实现不同的方法吗?
看起来您通常在java.lang.Comparable不指定类型参数的情况下实现接口。
public abstract class Area implements Comparable {
@Override
public int compareTo(Object other) {
if (other instanceof Area)
return new Double(getArea()).compareTo(other.getArea());
return -1; // or something else
}
abstract public double getArea();
}
Run Code Online (Sandbox Code Playgroud)
由于我只想将苹果与苹果进行比较,因此我认为指定类型是有意义的。
public abstract class Area implements Comparable<Area> {
@Override
public int compareTo(Area other) {
// ...
Run Code Online (Sandbox Code Playgroud)
如果我想介绍另一个类进行比较Area,我想我可以这样做:
public abstract class Area implements Comparable<Area>, Comparable<Volume> {
@Override
public int compareTo(Area other) {
// ...
}
@Override
public int compareTo(Volume other) {
// ...
} …Run Code Online (Sandbox Code Playgroud)