首页 > 解决方案 > C#中组合的主要目的是什么?

问题描述

我在互联网上阅读了许多文章和答案,所有这些文章都说明了必须在哪里使用组合,或者为什么组合必须优先于继承。但这不是我的问题!

作曲的主要目的是什么?对于那些说代码重用的人。我有另一个问题。当继承服务于代码重用的目的时,为什么要使用组合?

我想知道的一件事是,如果某些“Y”功能也用于相同目的,那么我为什么要使用“X”。应该有一个只由“X”服务的目的,而不是由任何其他“Y”服务。

所以,我的问题是,在这种情况下,Composition(X) & Inheritance(Y) 的目的是什么?

我是该领域的新手,如果有人回答我的问题,那将真的很有帮助。

标签: c#

解决方案


从个人经验来看,

使用继承

继承的使用是当一个函数需要来自一个对象的某些东西并且多个对象都有这些东西时,基本上,假设我们有这 3 个类:

//This is the base class, the one from which others inherit
abstract class WaitableObject
{
     protected WaitableObject(IntPtr handle) { Handle  = handle; }

     public IntPtr Handle { get; }
}

//Inherits from WaitableObject
class Object1 : WaitableObject
{
    public Object1() : base(new IntPtr(1))
    {
    }

    void DoSomething();
}

class Object2 : WaitableObject
{
    public Object2() : base(new IntPtr(2))
    {
    }

    int CalculateSomething(int a, int b);
}

然后我们有一个方法可以使用对象的Handle例如等待对象

bool WaitOn(WaitableObject obj)
{
   // do something with obj.Handle
}

因此,我们没有创建两个方法,一个接受Object1,另一个接受Object2,我们让这两个类都继承自同一个基类,它们都有共同点,也就是Handle. 同样适用于接口继承。

组合物的使用

组合的一个用途是让一个类型管理其他类型,这样当主类型被销毁时,这些类型就不会被意外访问。GameObjectUnity Engine 的类就是一个很好的例子。您可以向游戏对象添加单独的组件,但是,当主对象被销毁时,它的所有组件也会被销毁,因此如果持有已销毁游戏对象组件的类尝试访问它,它将被击中null 异常罪过该组件没有意义,因为它曾经附加到的游戏对象已被销毁。基本上,它是一个类型的一部分,只有在主类型还活着的情况下才应该被允许访问,在主类型被销毁后不要继续活着,这是 AFAIK 组合的主要用途。

A example which isn't 3rd party would be System.Windows.Forms.Form class, same principle with the components and same thing with the destruction.

多态性的使用 [阅读编辑说明]

多态主要用于当多个类/结构可以使用相同的东西时,例如System.IO's BinaryReader& BinaryWriter,它们都可以使用相同的流并且不需要单独打开2个,例如

public void AppendLastByte(string filename)
{
   // opens a Stream of the specified file with read & write rights
   Stream myFileStream = File.Open(filename, FileMode.Open, FileAccess.ReadWrite);

   myFileStream = (myFileStream.Length - 1); //set the position to the last byte.

   //Created a binary reader, so we can read the data of the stream.
   var reader = new BinaryReader(myFileStream);

   //Created a binary write, so we can write data to the stream.
   var writer = new BinaryWriter(newFileStream);

   //
   //Note that when a read/write operation is done the position in the underline stream is moved by the amount of bytes read/written.
   //

  //Read the last byte of the stream, as written above, the underline stream's position is now "myFileStream.Length", sins it was "myFileStream.Length - 1"
  byte lastByte = reader.ReadByte();

  //Wrote the read byte to the end of the file, aka appended it.
  writer.Write(lastByte);

  //disposal
  myFileStream.Close();
}

因此,我们只使用 1 个流,而不是管理 2 个流并消耗更多资源。使用多态的另一种可能性是限制可以对下划线对象执行的操作数量。让我们采取相同的 3 件事,Stream, BinaryReader& BinaryWriter, sinsStream确实具有读写能力,BinaryReader因此流有点仅限于读取,反之亦然BinaryWriter


推荐阅读