Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 我能';我不能从子类中的基类继承共享属性,可以吗?_Vb.net - Fatal编程技术网

Vb.net 我能';我不能从子类中的基类继承共享属性,可以吗?

Vb.net 我能';我不能从子类中的基类继承共享属性,可以吗?,vb.net,Vb.net,这是我的另一个“我认为这不可能,但我需要确认”问题 我有一个基类,用于一堆子类。现在,这个基类有一些子类使用的公共属性,比如Name。基类是一个抽象类(MustInherit)。从技术上讲,这意味着每次实例化子类时,它都会在内存中挂起自己的Name副本。问题是,Name将是给定子对象的所有实例的固定值。也就是说,Child1.Name将返回“child\u object1”,Child2.Name将返回“child\u object2” 该属性似乎是共享属性的完美候选,但随后问题就出现了。似乎如

这是我的另一个“我认为这不可能,但我需要确认”问题

我有一个基类,用于一堆子类。现在,这个基类有一些子类使用的公共属性,比如
Name
。基类是一个抽象类(MustInherit)。从技术上讲,这意味着每次实例化子类时,它都会在内存中挂起自己的
Name
副本。问题是,
Name
将是给定子对象的所有实例的固定值。也就是说,
Child1.Name
将返回
“child\u object1”
Child2.Name
将返回
“child\u object2”

该属性似乎是共享属性的完美候选,但随后问题就出现了。似乎如果我将
Name
定义为基类中的共享属性,那么不管从基类派生出什么子类,所有子类都将共享相同的
Name
,这正是共享属性(或方法等)的目的

我能想到的唯一解决方法是从基类中删除
Name
,并在每个子类中直接将其作为共享属性重新实现。不过,这似乎首先破坏了基类的功能。至少在原则上是这样

所以我的问题是,从设计的角度来看,解决这个问题的首选方法是什么?假设一个抽象基类至少有50个派生的子类。

我假设你说的“子对象”是指“子类”。不要混淆术语;这会让你的问题更加混乱

也就是说,我自己也曾多次使用过这种模式。您认为shared/static是正确的,但是您不能在这里应用它,因为从基类派生的类的每个实例都可以有不同的名称。我认为拥有一个被重写以返回常量值的抽象属性没有什么错

想想看——抽象成员的目的是允许子类提供其自己的实现。当你问一个物体“你叫什么名字?”时,你需要知道一些事情。子类本身是此类数据的理想场所,实现抽象成员非常有意义

如果Name属性将基于类型本身的名称返回某些内容,则可以使用
GetType().Name
获得该内容,因此可以将一些名称代码合并到属性的默认虚拟实现中,并在默认实现没有正确执行时覆盖它。这可以消除大量样板代码,而性能损失可以忽略不计


(要回答问题标题中提出的问题,是的,从技术上讲,一个类型的所有非私有共享/静态成员都由所有子类型继承。但您不能覆盖它们,因为这对共享/静态成员没有意义。)

@cdhowie:我对其进行了一些编辑。我认为它们是半可互换的术语。@cdhowie:我考虑过一种抽象的方法。但我不能将其与共享(至少在VB.Net中)混为一谈。我确实将派生类的名称作为常量存储在模块中,因此我可以在基类中定义抽象属性,在子类中重写并返回常量。最初的方法是通过保留基类中定义的公共属性,并让每个派生/子类在其无参数构造函数中执行一个
MyBase.Name=CHILD1_Name
来减少每个类中的混乱。@Kumba:But
Shared
意味着该属性只有一个实例,它属于基本类型。因此,在每个类的无参数构造函数中设置属性意味着每个对象的名称将是最近创建的对象的名称。你是对的;你不能把抽象和共享混为一谈。因此,删除共享修饰符并保持抽象。将“共享”视为创建一个全局变量——这在本文中没有任何意义,是吗?@cdhowie:对不起,我应该澄清一下,但当我声明我使用的是
MyBase.Name=…
方法时,这些实现没有共享,所以这并没有引起问题。我是说,我选择了这种方法,而不是定义在每个派生类中返回常量的只读属性,以减少代码混乱。如果我有50多个派生对象,每个派生对象都包含一个简单的只读名称属性,那么我认为与在构造函数中调用Name的基类副本相比,生成的代码要多得多。当然,我可能是分析过度了。我的坏习惯。为了继续下去,我现在正处于重新评估早期设计决策的阶段,因此寻求对我是否选择了一种半体面的方式,或者是否应该重新设计一些东西的意见。Name只是最好的例子……我在基类中有一些其他的属性,它们基本相同。