简体   繁体   English

类中的继承和类

[英]Inheritance and classes within classes

Here's some pseudo code to illustrate what I'm looking at. 这是一些伪代码来说明我在看什么。

public class Loader
{
    public Execute()
    {
       var currentPage = new ItemPageDocumentBuilder();
       while(reader.Read())
       {
           currentPage.Add(reader.XmlDoc);
       }
    }

    private class ItemsToLoad
    {
        private XmlDocument _page
        public void Add(XmlElement itemelement)
        {
            _page.DocumentElement.AppendChild(itemElement);
        }
    }
}

I need to derive a class from Loader, and then override the Add method of the ItemsToLoad class inside it, and then call base.Execute(). 我需要从Loader派生一个类,然后重写其中的ItemsToLoad类的Add方法,然后调用base.Execute()。 In other words I want the Execute() method of my derived class to be exactly the same as that of Loader, but to use the overridden Add method of ItemsToLoad to to its work. 换句话说,我希望派生类的Execute()方法与Loader完全相同,但是要使用ItemsToLoad的重写Add方法来工作。

I suspect the neatest way to do this would be to remove ItemsToLoad from inside Loader, and make it abstract, correct? 我怀疑最简单的方法是从Loader中删除ItemsToLoad,并使其抽象化,对吗?

If I couldn't do that, out of interest, what's the best solution? 如果出于兴趣我不能这样做,最好的解决方案是什么?

If I understand your requirement, you have two responsabilities: executing something (which is always the same), and adding something (which differs). 如果我理解您的要求,则您有两个责任:执行某些操作(始终相同)和添加某些内容(不同)。

I would do it much simpler, without inheritance and inner classes. 如果没有继承和内部类,我会做得多简单。

For the adding task, you define an interface: 对于添加任务,您定义一个接口:

public interface IItemAdder
{
    void Add();
}

And one ore more implementations: 还有一个或多个实现:

public class ItemAdder1 : IItemAdder
{
    public void Add()
    {            
         // specific implementation here
    }
}

Then, you have a Loader, in which you inject a specific instance of item adder: 然后,您有一个加载器,在其中加载了项添加器的特定实例:

public class Loader : ILoader
{
    private IItemAdder _itemAdder;
    public Loader(IItemAdder itemAdder)
    {
        _itemAdder = itemAdder;
    }
    public void Execute()
    {
        // use injected item adder to do work
        _itemAdder.Add();
    }       
}

public interface ILoader
{
    void Execute();
}

And so usage is: 因此用法是:

var loader = new Loader(new ItemAdder1());
loader.Execute();    

This way everything is injected, can be replaced and mocked easily; 这样,一切都可以注入,可以轻松地替换和嘲笑; and you clearly separate concerns. 并且您清楚地将关注点分开。

Here is a suggestion (Syntax might not be correct though): 这是一个建议(语法可能不正确):

public class Loader
{
    ItemsToLoad item;
    public Loader(ItemsToLoad item) {
      this.item = item;
    }

    public Execute()
    {
       // do things using item like item.add();
    }
}

interface ItemsToLoad
{
    void add();
}

class ItemsToLoad1: ItemsToLoad
{
    void add(){
        // implementation
    }
}

class ItemsToLoad2: ItemsToLoad
{
    void add(){
        // implementation
    }
}

And here is how to use them; 这里是如何使用它们;

ItemsToLoad item;
if (some condition) {
   item = new ItemsToLoad1()
} else {
   item = new ItemsToLoad2()
}

Loader loader = new Loader(item);
loader.execute();

You can inherit both classes and inject child sub-class object to its parent. 您可以继承两个类,并将子子类对象注入其父类。

class Loader
    {

        public void Execute(ItemsToLoad argObj)
        {
            if(argObj == null)
                argObj = new ItemsToLoad();

            argObj.Add(19);
        }

        public class ItemsToLoad
        {
            public virtual void Add(int a)
            {
                Console.WriteLine("Reached ItemsToLoad.");
            }
        }
    }

class ChildLoader:Loader
    {
        public void Execute(ItemsToLoad argObjLoader)
        {
            if (argObjLoader == null)
                argObjLoader = new ChildItemsToLoad();

            base.Execute(argObjLoader);
    }

    class ChildItemsToLoad : Loader.ItemsToLoad
    {

        public override void Add(int b)
        {
            Console.WriteLine("Reached ChildItemsToLoad.");
        }

    }
}

And can start with 并且可以开始于

ChildLoader obj999 = new ChildLoader();
obj999.Execute(null);

I need to derive a class from Loader, and then override the Add method of the ItemsToLoad class inside it, and then call base.Execute(). 我需要从Loader派生一个类,然后重写其中的ItemsToLoad类的Add方法,然后调用base.Execute()。 In other words I want the Execute() method of my derived class to be exactly the same as that of Loader, but to use the overridden Add method of ItemsToLoad to to its work. 换句话说,我希望派生类的Execute()方法与Loader完全相同,但是要使用ItemsToLoad的重写Add方法来工作。

You need to override Loader , not ItemsToLoad . 您需要覆盖Loader ,而不是ItemsToLoad You haven't shown the code that uses ItemsToLoad , so it's difficult to be specific - but at the very least, you would need to override the new ItemsToLoad to point to your subclass. 您尚未显示使用ItemsToLoad的代码,因此很难具体说明-但至少,您需要重写new ItemsToLoad来指向您的子类。 Also, ItemsToLoad is private - meaning you can't use it except from within Loader . 另外, ItemsToLoad是私有的-这意味着您只能在Loader使用它。 As it is now, you'd need a completely rewritten ItemsToLoad and to override every method in Loader that uses ItemsToLoad . 现在,您需要完全重写的ItemsToLoad并覆盖Loader中使用ItemsToLoad每个方法。

If you control the Loader class, the easiest changes would probably be to abstract out the creating of ItemsToLoad and open up ItemsToLoad so it can be subclassed. 如果控制Loader类,最简单的更改可能是抽象出ItemsToLoad的创建并打开ItemsToLoad以便可以将其子类化。 Something like: 就像是:

public class Loader {
   private ItemsToLoad Items { get; set; }

   protected virtual ItemsToLoad CreateItemsToLoad() {
      return new ItemsToLoad();
   }

   protected class ItemsToLoad {
      public virtual void Add() {
      }
   }
}

public class MyOtherLoader : Loader {
   protected override ItemsToLoad CreateItemsToLoad() {
      return new MyOtherItemsToLoad();
   }

   private class MyOtherItemsToLoad : ItemsToLoad {
      public override void Add() {
      }
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM