如何创建一个类,可以创建另一个类的实例并访问所有者的私有成员 [英] How do I make a class that can create an instance of another class and access private members of the owner

查看:201
本文介绍了如何创建一个类,可以创建另一个类的实例并访问所有者的私有成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道我想做什么打破面向对象的指导方针或不,所以我会解释我在做什么,希望你们可以告诉我一个更好的方式,如果我错了。我之前尝试过这个问题,但我给了一个很差的例子,所以我认为它只是引起更多的困惑。

I am not sure if what I want to do breaks Object oriented guidelines or not so I will explain what I am doing and hopefully you guys can show me a better way if I am wrong. I tried asking this question before but I gave a poor example so I think it just caused more confusion.

所以我有一个主类,USBCommunicator。构造函数获取您要与之通信的设备类型的产品ID。 USBCommunicator类也有一个特定序列号的属性。 USBCommunicator具有OpenConnection和CloseConnection方法,它们将打开或关闭数据流以在USB设备和PC之间传输数据。

So I have a main class, USBCommunicator. The constructor takes a Product ID of the type of device that you want to talk to. The USBCommunicator class also has a property for a specific serial number to talk to. USBCommunicator has OpenConnection and CloseConnection methods which will open or close a data stream to transfer data between the USB device and the PC.

要通过流发送数据,我希望USBCommunicator能够创建一个Report类的实例,设置一些参数,如超时,ReportID等,然后调用Report类的Send()方法来实际发送数据。我不认为除USBCommunicator之外的任何类都应该能够创建一个Report类的实例。 (例如,Boat lass应该不能创建CarDoor类的实例,因为船不能有车门。)最后,我最初认为Report类应该能够访问USBCommunicator的成员但我猜这不是真的。如果USBCommunicator打开流的设备,所有报表真正需要的是一个传递的参数,它是开放流的引用/句柄。但是,流应该是什么形式,它将允许它通过高级应用程序?公共财产?这似乎不对。

To send data across the stream I want the USBCommunicator to be able to create an instance of a Report class, set some parameters such as timeouts, ReportID's etc, and then call a Send() method of the Report class to actually send the data. I don't think any class other than USBCommunicator should be able to create an instance of the Report class. (For example, a Boat lass shouldn't be able to create instances of CarDoor class because boat can't have a car door.) Finally, I was originally thinking that the Report class should be able to have access to the members of USBCommunicator but I guess that is not true. If USBCommunicator opens the stream the the device, all Report really needs is a parameter passed in that is a reference/handle to the open stream. But what form should that stream be that it would allow it to be passed by the high level application? a public property? That doesn't seem quite right.

这是我到目前为止的...

So here is what I have so far...

namespace USBTools
{
    class HighLevelApplication
    {
        void main()
        {
            USBCommunicator myUSB = new USBCommunicator("15B3");
            myUSB.SerialNumber = "123ABC";
            myUSB.OpenConnection();
            myUSB.Report ReportToSend = new myUSB.Report(//how do I pass the stream here?);
                //It would be nice if I didn't have to pass in the stream because the stream shouldn't
                //be publicly available to the HighLevelApplication class right?
            ReportToSend.ReportID = 3;
            ReportToSend.Timeout = 1000;
            ReportToSend.Data = "Send this Data";
            ReportToSend.Send();
        }
    }

    class myUSB
    {
        myUSB(string PID)
        {
            //...
        }

        // public SerialNumber property

        // private stream field ???

        // public OpenConnection and CloseConnection methods

        class Report
        {
            Report(stream StreamToUse)
            {
                //...
            }
            Send()
            {
                //send the data
            }
        }
    }
}


推荐答案

由于 USBCommunicator 管理所有重要资源(包括流的生命周期),应用程序应调用 USBCommunicator.Send ,而不是 Report.Send

Since USBCommunicator manages all the important resources (including the stream's lifetime), applications should call USBCommunicator.Send, not Report.Send:

public class USBCommunicator {
    public void Send(Report report) {

        // If it's appropriate, this method can also Open 
        // and Close the stream so callers don't have to.

        report.Send(this.stream);
    }
}

发送 internal,因此它不是公共API的一部分,应用程序可以这样做:

Next, make Report.Send internal so it isn't part of the public API, and applications can do this:

public void main(string[] args) {
        USBCommunicator myUSB = new USBCommunicator("15B3");
        myUSB.SerialNumber = "123ABC";
        myUSB.OpenConnection();

        Report report = new Report(3, 1000, "Send this Data");
        myUSB.Send(report);
}








我不认为除了
之外的任何类USBCommunicator应该能够
创建一个Report
类的实例。

I don't think any class other than USBCommunicator should be able to create an instance of the Report class.

您当前的设计并不能防止这种情况 - 实际上,您的示例应用程序创建了 Report 类的实例。如果你真的想隐藏报表类,你应该把它私密到 USBCommunicator ,并将其属性推出到通讯器的界面,如下:

Your current design doesn't prevent this - indeed, your sample application is creates an instance of the Report class. If you really want to hide the report class, you should make it private to USBCommunicator and push its attributes out to the communicator's interface like this:

// USBCommunicator
public void Send(int reportID, int timeout, string data) {
    Report report = new Report(reportID, timeout, data);
    report.Send(this.stream);
}

这篇关于如何创建一个类,可以创建另一个类的实例并访问所有者的私有成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆