了解 C# 中的组合

jue*_*ra7 2 c# composition

我想更好地理解组合而不是继承。我看了一些教程,它们很好地解释了这些概念,但使用的是我更熟悉的语言,例如 Python。然而,我目前正在学习 C#,正在努力运用我在该主题上学到的知识,想知道是否有人可以提供帮助。这是我的代码:

using System;

namespace Composition
{
    class Program
    {
        static void Main(string[] args)
        {
            SuperBot steven = new SuperBot(new Dog(),new Robot());
            steven.Bark();


        }
    }

    class Dog
    {
        public void Bark()
        {
            Console.WriteLine("Woof");
        }

    }

    class Robot
    {
        public void Move()
        {
            Console.WriteLine("I'm moving!");
        }
    }

    class CleanRobot
    {
        public void Clean()
        {
            Console.WriteLine("Just keep dusting, just keep dusting");
        }
    }

    class SuperBot
    {
        // can clean, move and bark
        public Dog o1;
        public Robot o2;
        public CleanRobot o3;

        public SuperBot(Dog dog, Robot robot)
        {
            this.o1 = dog;
            this.o2 = robot;

        }

    }

}
Run Code Online (Sandbox Code Playgroud)

本质上,我有一个Dogthat can bark、一个Robotthat canmove和一个CleanRobotthat can clean。我想创建一个可以移动、吠叫和清洁的超级机器人,并使用组合来实现这一目标。

我有两个主要问题:

  1. 上面是我到目前为止编写的代码,但它不允许我Bark在我的SuperBot对象上调用该方法,因为它说SuperBot类不包含此方法。

  2. 如果我的Dog类也可以Eat()但我不想在我的SuperBot类中使用此方法,我将如何使用组合?

真的很感谢任何帮助 - 努力解决这个问题!

更新 - 尝试使用界面

using System;

namespace Composition
{
    public interface ICanBark
    {
        string Bark();
    }

    public interface ICanMove
    {
        string Move();
    }

    public interface ICanClean
    {
        string Clean();
    }

    class Program
    {


    static void Main(string[] args)
        {
            SuperBot steven = new SuperBot();
            steven.Bark();

        }
    }

    class Dog : ICanBark 
    {
        public string Bark()
        {
            return "Woof"; 
        }
    }

    class Robot : ICanMove
    {
        public string Move()
        {
           return "I'm moving";
        }
    }

    class CleanRobot : ICanClean
    {
        public string Clean()
        {
           return "Just keep dusting, just keep dusting";
        }
    }

    class SuperBot : ICanBark, ICanMove, ICanClean
    { 
        public string Bark()
        {
            return "Barking";
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

use*_*290 5

当在您的示例中使用组合时,不幸的是,您还必须在组合类中实现公开的方法:

class SuperBot
{
    // can clean, move and bark
    public Dog o1;
    public Robot o2;
    public CleanRobot o3;

    public SuperBot(Dog dog, Robot robot, CleanRobot cleanRobot)
    {
        this.o1 = dog;
        this.o2 = robot;
        this.o3 = cleanRobot;
    }

    public void Bark() => o1.Bark();
    public void Move() => o2.Move();
    public void Clean() => o3.Clean();
}
Run Code Online (Sandbox Code Playgroud)

这将解决您的编译器错误。此外,如果您向DogRobot或添加更多方法CleanRobot,它们不会影响所SuperBot提供的内容,即如果Dog有一个方法Eat()SuperBot则不会有此方法,除非您也添加它。

从概念上讲,如果您将 a 建模SuperBot为实际上由 a Dog、 aRobot和 a组成,则可以像这样使用组合CleanRobot。然后SuperBot用它Dog来吠叫并用它CleanRobot来清洁。


编辑(来自评论):

如果你想要一个调用的函数Bark

    public void GoodBoy(Dog dog)
    {
        dog.Bark();
    }
Run Code Online (Sandbox Code Playgroud)

您不能将 a 传递SuperRobot给此方法。在这种情况下,您需要一个包含该Dog方法的通用接口。SuperRobotBark