【问题标题】:Why do people declare a variable of a base type of the object they assign to it? [closed]为什么人们要声明他们分配给它的对象的基本类型的变量? [关闭]
【发布时间】:2016-07-08 18:13:09
【问题描述】:

这是一个例子:

abstract class baseClass
{
  void aMethod
  {
    //something here...
  }
}

class derivedClass : baseClass
{
  void aMethod
  {
    //something here...
  }
}

void main()
{
  baseClass Object_1 = new derivedClass();
}

为什么 Object_1 被声明为 baseClass?程序员为什么要这样做? Object_1 是什么类型?它是基类还是派生类?如果我的 Object_1 是这样创建的,会有什么不同:

derivedClass Object_1 = new derivedClass();

?

我正在学习 C#,在这种情况下,这是我最感兴趣的环境。

【问题讨论】:

  • 当您在编译时不知道派生类型是什么时,这经常在工厂模式中使用。此外,有时另一个类需要保存对某种类型的基类的引用,但它在编译时并不确切知道它是什么,而是在运行时计算出来。
  • 为了通过其基类的接口访问对象。我可以有一个包含法拉利、福特、本田等的 List,但是如果我想同时启动所有汽车,那么我可以使用 Car 的 start() 方法的基类并遍历调用该方法的 Cars , 例如。这样,您可以将具有共同基类但不同子类的对象组合在一起。
  • 了解 SOLID 原则,尤其是 Liskov-Substitution Principle
  • “Object_1 是使用 baseClass 初始化的”通常并不意味着“Object_1 声明为 baseClass 的实例”。除非你的意思是别的,请编辑你的帖子。

标签: c# class object inheritance


【解决方案1】:

为什么 Object_1 是使用 baseClass 类初始化的?

事实并非如此。看看new后面是什么类型,它是派生类型。您在这里拥有的是已使用基类型作为引用类型引用的派生类型实例。

程序员为什么要这样做?

拥有类型化引用意味着您可以使用对象的成员。根据使用的层次结构的实际类型,您可以访问相应的成员集。

Derived o = new Derived()
o.xxx  <- full access to instance members

Base o = new Derived()
o.xxx. <- access is limited to members that are defined in the Base class

object o = new Derived()
o.xxx. <- you can always see an instance as of 'object' type
          and have most limited interface

请注意,每次实例的实际类型都是Derived,但由于某种原因,您决定通过不同的“眼镜”来查看它。

Object_1 是什么类型

实际类型始终是位于new 运算符之后的类型。

如果我的 Object_1 是这样创建的,会有什么不同:

实例本身没有区别,但您可以通过不同的方式访问其成员。在像 C# 这样的语言中,您始终可以安全地将实例转换为其基本类型(或层次结构中的任何类型),但请注意,您不能总是在层次结构中执行相同的操作:

Derived1 d = new Derived1();
Base     b = (Base)d;

// d and b point to the very same instance but they differ on what properties you are allowed to access

Derived2 d2 = (Derived2)b;

// casting to a derived type would work only if the instance was of this actual type
// in a worst case such cast would then end with a run-time error

【讨论】:

  • 感谢您的详细解答。关于您的 (1) 示例:当您定义 Base o = new Derived();你说对象 o 只能访问在基类中定义的成员。如果派生类的成员比基类多怎么办?我们将无法访问它们。如何处理?关于您的(2)示例:您创建了 Derived 类的对象 d。然后你创建一个对该对象的引用 b ,但我不明白为什么你将 d 对象转换为 Derived 类型 - 但你希望 b 确实是 Base 类型,而不是 Derived 类型。
  • 首先,如果可能的话,要访问更多成员,您可以随时向上投。至于例子,更正了,我的错误。
【解决方案2】:

一个实际的例子:你想将一组东西传递给一个方法。该方法应该对每一件事都做一些事情。

在将集合传递给方法之前,必须先创建它。要创建事物的集合,您需要一个具有 Add 方法的类。一个 List 类就可以了。

对于接收方法来说,向集合中添加东西的能力是无关紧要的。它只需要能够枚举集合中的事物。所以你传递的是 IEnumerable,而不是 List。

通常,将实例分配给基本类型变量可以消除噪音并缩小进行假设的空间。它说“此时子类型并不重要,所以这并不比基本类型复杂。”让你心情舒畅。

【讨论】:

    猜你喜欢
    • 2019-03-27
    • 2023-04-07
    • 2014-11-09
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多