0

我正在开发一个从各种在线档案中抓取内容的程序,但对 OOP 还是陌生的。我认为最好的方法是有一个指定共享变量和方法的父类,然后是每个存档的子类,然后包含从该特定站点获取信息的特定方法,例如 GrabStoryVariables() 存在于每个子类以适应该档案的个人需求。该程序在文本框中获取一个 URL,然后从那里它将确定使用 URL 来实例化哪个子类。

我遇到的问题是弄清楚如何创建子类对象并使其可供整个程序访问。例如,要创建 FanFictionAuthors 的实例: FanBook:

private void btnGetInfo(object sender, EventArgs e)
{
  CreateBook();
}

private void CreateBook()
{
  if (addressBar.Text.Contains("fanficauthors.net"))
  {
    FanFictionAuthors myBook = new FanFictionAuthors();
  }
  return;
}

myBook 的作用域只是 CreateBook() 函数,所以这种方法不会奏效。有关处理此问题的最佳方法的任何建议?我用它作为一种更好地学习编程的方法,所以“正确”的方法是我想要弄清楚的,不管是什么。

编辑:该程序的特定功能是从 fanfiction.net、fictionpress.com 或任意数量的其他在线故事档案中获取在线故事的 URL。每个故事都有一组共享属性,例如标题、章节数、字长、章节标题和故事的实际内容。该程序编译所有这些以创建单个 html 文档(后来被扩展以允许不同的电子书格式),而不是一堆小的单个章节文件。

考虑到这一点,每个存档之间唯一不同的部分是从特定存档中获取变量的方法以及如何根据存档的功能在章节之间进行迭代。

目前我正在做的只是在启动主窗体后立即创建一个 myBook 对象,然后为获取变量并进行迭代的函数创建一个不同的方法名称。然而,随着我添加更多档案,这变得更加复杂。我最初想做的只是将 myBook 转换为单个存档类型(在本例中为 FanFictionAuthors),以获取使用其特定功能的能力。在网上看,从父母到孩子的铸造似乎并不容易,也不推荐,所以我不知道还有什么方法可以解决这个问题。

这是该项目的 GitHub 链接。这个版本有点过时了,但让你看看我目前是如何处理这个的:https ://github.com/benroth/fBook

4

3 回答 3

1

创建一个超类,您可以在其中使用公共属性和方法:

public class FanBook
{
    // use a common constructor
    public FanBook(string url)
    {
        grabHtml(url);
        // ...
    }

    protected string grabHtml(string address) { // SNIP }

    protected void CreateStoryHeader() { // SNIP }

    // other common methods which are the same for every subclass (maybe BuildToc, GetStory, etc.)

    // maybe if you want some easy access to attributes, you could add a dictionary
    public void Dictionary<string, string> Attributes;

    // Then use abstract methods to define methods that are different for subclasses
    protected abstract void GrabStoryVariables();
    protected abstract void GenerateStoryInfo();
}

然后创建一个派生自的子类Book

public class FFNETBook : FanBook {
    // FFNETBook constructor to call contructor from FanBook too
    public FFNETBook(string url) : FanBook(url) {
        // specific initializations for FFNET

    }

    public override void GrabStoryVariables() { // special implementation for FFNET here }

    public override void GenerateStoryInfo() { // special implementation for FFNET here }
}

我知道当您没有太多经验时,很难掌握 OOP。因此,请随时提出问题。如果你做对了,那么你永远不需要转换成子类。

要回答评论中的问题:

您可以在form1.cs文件中创建一个类变量:

private FanBook currentBook;

private void CreateBook()
{
    currentBook = new FFNETFanBook("http://...");
}

private void AnotherMethod() {
    if ( currentBook != null ) {
        currentBook.GrabStoryVariables();
    } else {
        throw new Exception("Book not initialized yet.");
    }
}
于 2012-10-21T06:50:51.533 回答
1

实现一个名为 IAuthors 的接口并定义你想要的方法

Interface IAuthors
{
//method
void authorMethod();
}

跨类实现接口

Public Class FanFictionAuthors:IAuthors
{
public void authorMethod()
{
//fanfiction specific action
}
}

Public class SciFiAuthors:IAuthors
{
public void authorMethod()
{
//scifiauthor specific action
}
}

现在对现有代码进行以下更改

private void btnGetInfo(object sender, EventArgs e)
{
  IAuthors auth=CreateBook();//Use a Interface ref
  auth.authorMethod();//Runtime will decide which authorMethod to call depending 
                      //on the object returned.
}

//Note that i am returning the Interface type instead of the void
private IAuthors CreateBook()
{
  if (addressBar.Text.Contains("fanficauthors.net"))
  {
    return new FanFictionAuthors();//Return your object
  }elseif(addressBar.Text.Contains("scificauthors.net"))
  {
    return new SciFiAuthors();//Return your object
  }
}
于 2012-10-21T06:51:49.337 回答
0

您可以在父级中创建一个列表并将子级添加到该列表中。然后,您可以遍历该列表以查看孩子是否完成等。

ChildList.Add(new fan....)
于 2012-10-21T06:52:51.113 回答