抽象 class 构造函数继承与内部 classes objects
abstract class constructor inheritence with inner classes objects
假设我有一个抽象 class A。我有一些内在的 class 像这里:
public abstract class A
{
public InnerOne x;
public InnerTwo y;
public A(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
public class InnerOne
{
public virtual double value(){
return 0;
}
}
public class InnerTwo
{
public virtual double value(){
return 0;
}
}
}
然后我得到了这样的孩子:
public class B: A
{
public B():base(){
}
public class InnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class InnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
所以我认为当我像那样调用 B
构造函数时,我将通过创建它的内部 classes 实例来初始化 x
和 y
。但实际上它不是那样工作的。当我像这里一样调用 vaule
函数时,它 returns 归零。
A newobject = new B();
var bv1 = B.x.value();
var bv2 = B.y.value();
有没有办法通过它的内部 class objects 强制 B
class 初始化它的 x
和 y
字段(不是with objects from parent abstract class) without re-writing it's constructor?
即使您在 A 或 B 中定义了 classes,它们仍然是 public 并且可以在 A 或 B 之外访问。这与定义的 class 没有区别在 A 或 B 之外。
想象一下在 class A 和 B 之外定义 InnerOne
和 InnerTwo
的相同代码。它将具有与上述相同的行为。您的困惑根源是误解了内部 class 用法。
为了获得 100,在 B 中,您需要用覆盖这些值的实例显式替换 X 和 Y 变量的实例。除非你这样做,否则你不会得到 100。
public class B: A
{
public B():base(){
X = new OverridenInnerOne();
Y = new OverridenInnerTwo();
}
public class OverridenInnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class OverridenInnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
'inner class' 方面(嵌入 class 定义)在这里只是分散注意力,没有任何作用。
然后回答这个问题:不,你不能让 'virtual constructors' 这样工作。
当然有很多方法可以获得 100
而不是 0
作为返回值,但是这个问题太人为化了,无法提出一个建议。
B.x
和 B.y
是 A.InnerOne
和 A.InnerTwo
的实例,因此您看到值 returned 为 0,因为它们什么都没有与 B.InnerOne
或 B.InnerTwo
.
相关
以下 B
构造函数会将 x
和 y
分配给 B.InnerOne
和 B.InnerTwo
的实例,这将 return 100。
public B(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
如果您希望 A
以您期望的方式工作,您需要从 B
构造函数传递您想要的内部类型,并在 A
构造函数,类似于:
public B():base(typeof(InnerOne),typeof(InnerTwo)) { ... }
使用 Activator.CreateInstance
将允许您在 A
的构造函数中创建这些类型。
如果您总是希望以这种方式使用 A
,Enigmativity 的通用解决方案会更好,或者这种方式允许您为 A
设置多个构造函数,因此您可以选择传入不同的类型。
你可以做到,但你必须更改 class A
的定义 - 它变得非常毛茸茸。
这里是A
:
public abstract class A<I1, I2>
where I1 : A<I1, I2>.InnerOne, new()
where I2 : A<I1, I2>.InnerTwo, new()
{
public InnerOne x;
public InnerTwo y;
public A()
{
this.x = new I1();
this.y = new I2();
}
public class InnerOne
{
public virtual double value()
{
return 0;
}
}
public class InnerTwo
{
public virtual double value()
{
return 0;
}
}
}
这里是B
:
public class B: A<B.InnerOne, B.InnerTwo>
{
public B():base(){ }
public class InnerOne: A<InnerOne, InnerTwo>.InnerOne
{
public override double value()
{
return 100;
}
}
public class InnerTwo: A<InnerOne, InnerTwo>.InnerTwo
{
public override double value()
{
return 100;
}
}
}
假设我有一个抽象 class A。我有一些内在的 class 像这里:
public abstract class A
{
public InnerOne x;
public InnerTwo y;
public A(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
public class InnerOne
{
public virtual double value(){
return 0;
}
}
public class InnerTwo
{
public virtual double value(){
return 0;
}
}
}
然后我得到了这样的孩子:
public class B: A
{
public B():base(){
}
public class InnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class InnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
所以我认为当我像那样调用 B
构造函数时,我将通过创建它的内部 classes 实例来初始化 x
和 y
。但实际上它不是那样工作的。当我像这里一样调用 vaule
函数时,它 returns 归零。
A newobject = new B();
var bv1 = B.x.value();
var bv2 = B.y.value();
有没有办法通过它的内部 class objects 强制 B
class 初始化它的 x
和 y
字段(不是with objects from parent abstract class) without re-writing it's constructor?
即使您在 A 或 B 中定义了 classes,它们仍然是 public 并且可以在 A 或 B 之外访问。这与定义的 class 没有区别在 A 或 B 之外。
想象一下在 class A 和 B 之外定义 InnerOne
和 InnerTwo
的相同代码。它将具有与上述相同的行为。您的困惑根源是误解了内部 class 用法。
为了获得 100,在 B 中,您需要用覆盖这些值的实例显式替换 X 和 Y 变量的实例。除非你这样做,否则你不会得到 100。
public class B: A
{
public B():base(){
X = new OverridenInnerOne();
Y = new OverridenInnerTwo();
}
public class OverridenInnerOne: A.InnerOne
{
public override virtual double value(){
return 100;
}
}
public class OverridenInnerTwo: A.InnerTwo
{
public override virtual double value(){
return 100;
}
}
}
'inner class' 方面(嵌入 class 定义)在这里只是分散注意力,没有任何作用。
然后回答这个问题:不,你不能让 'virtual constructors' 这样工作。
当然有很多方法可以获得 100
而不是 0
作为返回值,但是这个问题太人为化了,无法提出一个建议。
B.x
和 B.y
是 A.InnerOne
和 A.InnerTwo
的实例,因此您看到值 returned 为 0,因为它们什么都没有与 B.InnerOne
或 B.InnerTwo
.
以下 B
构造函数会将 x
和 y
分配给 B.InnerOne
和 B.InnerTwo
的实例,这将 return 100。
public B(){
this.x = new InnerOne();
this.y = new InnerTwo();
}
如果您希望 A
以您期望的方式工作,您需要从 B
构造函数传递您想要的内部类型,并在 A
构造函数,类似于:
public B():base(typeof(InnerOne),typeof(InnerTwo)) { ... }
使用 Activator.CreateInstance
将允许您在 A
的构造函数中创建这些类型。
如果您总是希望以这种方式使用 A
,Enigmativity 的通用解决方案会更好,或者这种方式允许您为 A
设置多个构造函数,因此您可以选择传入不同的类型。
你可以做到,但你必须更改 class A
的定义 - 它变得非常毛茸茸。
这里是A
:
public abstract class A<I1, I2>
where I1 : A<I1, I2>.InnerOne, new()
where I2 : A<I1, I2>.InnerTwo, new()
{
public InnerOne x;
public InnerTwo y;
public A()
{
this.x = new I1();
this.y = new I2();
}
public class InnerOne
{
public virtual double value()
{
return 0;
}
}
public class InnerTwo
{
public virtual double value()
{
return 0;
}
}
}
这里是B
:
public class B: A<B.InnerOne, B.InnerTwo>
{
public B():base(){ }
public class InnerOne: A<InnerOne, InnerTwo>.InnerOne
{
public override double value()
{
return 100;
}
}
public class InnerTwo: A<InnerOne, InnerTwo>.InnerTwo
{
public override double value()
{
return 100;
}
}
}