C# 如何创建一个类来创建另一个类的实例并访问所有者的私有成员
我不确定我想做的事情是否违反了面向对象的准则,所以我会解释我在做什么,希望你们能给我一个更好的方法,如果我错了。我以前试过问这个问题,但我举了一个糟糕的例子,所以我认为这只会引起更多的混乱 所以我有一个主类,USBCommunicator。构造函数获取您想要与之对话的设备类型的产品ID。USBCommunicator类还有一个特定序列号的属性,可以与之通信。USBCommunicator具有OpenConnection和CloseConnection方法,可以打开或关闭数据流,以便在USB设备和PC之间传输数据 要跨流发送数据,我希望USBCommunicator能够创建报表类的实例,设置一些参数,如超时、报表ID等,然后调用报表类的send()方法来实际发送数据。我认为除了USBCommunicator之外,任何类都不能创建Report类的实例。(例如,一个Boat类不应该能够创建CarDoor类的实例,因为Boat不能有车门。)最后,我最初认为Report类应该能够访问USBCommunicator的成员,但我猜这不是真的。如果USBCommunicator打开设备的流,则报告真正需要的只是传入一个参数,该参数是打开的流的引用/句柄。但是,该流应该是什么形式,以允许高级应用程序传递它呢?公共财产?这似乎不太正确 这就是我到目前为止所拥有的C# 如何创建一个类来创建另一个类的实例并访问所有者的私有成员,c#,class,inheritance,oop,C#,Class,Inheritance,Oop,我不确定我想做的事情是否违反了面向对象的准则,所以我会解释我在做什么,希望你们能给我一个更好的方法,如果我错了。我以前试过问这个问题,但我举了一个糟糕的例子,所以我认为这只会引起更多的混乱 所以我有一个主类,USBCommunicator。构造函数获取您想要与之对话的设备类型的产品ID。USBCommunicator类还有一个特定序列号的属性,可以与之通信。USBCommunicator具有OpenConnection和CloseConnection方法,可以打开或关闭数据流,以便在USB设备和
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
}
}
}
}
您不显式访问私有成员,而是提供从报表类返回私有变量的公共属性 另外,只要您的报表类被标记为
public
,您就可以执行以下操作:
Report r = new Report();
在主USBCommunicator类中。但决不要将成员变量公开为公共变量,它们在报表中应该是私有的,但您应该包含公共属性来访问这些私有成员。如果您不显式访问私有成员,则提供从报表类返回私有变量的公共属性 另外,只要您的报表类被标记为
public
,您就可以执行以下操作:
Report r = new Report();
在主USBCommunicator类中。但决不要将成员变量公开为公共变量,它们在报表中应该是私有的,但您应该包含公共属性来访问这些私有成员。为什么不传递整个类(通过引用或复制)
myUSB.Report ReportToSend=new myUSB.Report(ParentClassWithStream)代码>
myUSB.Report必须有私人成员才能保存引用
...
class Report
{
ParentClassWithStream PC
Report(ParentClassWithStream p)
{
PC = p
//...
}
Send()
{
//send the data
}
}
...
你为什么不通过整个课程(通过参考或复制)
myUSB.Report ReportToSend=new myUSB.Report(ParentClassWithStream)代码>
myUSB.Report必须有私人成员才能保存引用
...
class Report
{
ParentClassWithStream PC
Report(ParentClassWithStream p)
{
PC = p
//...
}
Send()
{
//send the data
}
}
...
以下内容将满足您的要求。其思想是将报表类的接口与实际实现分离。它允许您创建一个只有USBCommunicator对象才能创建的实现类
public abstract class Report
{
protected Report() { }
public int ReportID {get; set;}
public int Timeout {get; set;}
public string Data {get; set; }
public abstract void Send();
}
public class USBCommunicator
{
private Stream m_stream;
public USBCommunicator (string PID)
{
//...
}
//Callers create new report objects via a method instead of directly using 'new'
public Report CreateReport()
{
return new ReportImpl(m_stream);
}
//Provides the implementation of the abstract methods of the Report class.
private class ReportImpl : Report
{
private Stream m_stream;
public ReportImpl(Stream stream)
{
m_stream = stream;
}
public void override Send()
{
//put implementation of Send here.
}
}
}
然后,您的高级应用程序将变成:
class HighLevelApplication
{
void main()
{
USBCommunicator myUSB = new USBCommunicator("15B3");
myUSB.SerialNumber = "123ABC";
myUSB.OpenConnection();
Report reportToSend = myUSB.CreateReport();
reportToSend.ReportID = 3;
reportToSend.Timeout = 1000;
reportToSend.Data = "Send this Data";
reportToSend.Send();
}
}
以下内容将满足您的要求。其思想是将报表类的接口与实际实现分离。它允许您创建一个只有USBCommunicator对象才能创建的实现类
public abstract class Report
{
protected Report() { }
public int ReportID {get; set;}
public int Timeout {get; set;}
public string Data {get; set; }
public abstract void Send();
}
public class USBCommunicator
{
private Stream m_stream;
public USBCommunicator (string PID)
{
//...
}
//Callers create new report objects via a method instead of directly using 'new'
public Report CreateReport()
{
return new ReportImpl(m_stream);
}
//Provides the implementation of the abstract methods of the Report class.
private class ReportImpl : Report
{
private Stream m_stream;
public ReportImpl(Stream stream)
{
m_stream = stream;
}
public void override Send()
{
//put implementation of Send here.
}
}
}
然后,您的高级应用程序将变成:
class HighLevelApplication
{
void main()
{
USBCommunicator myUSB = new USBCommunicator("15B3");
myUSB.SerialNumber = "123ABC";
myUSB.OpenConnection();
Report reportToSend = myUSB.CreateReport();
reportToSend.ReportID = 3;
reportToSend.Timeout = 1000;
reportToSend.Data = "Send this Data";
reportToSend.Send();
}
}
由于USBCommunicator
管理所有重要资源(包括流的生存期),应用程序应该调用USBCommunicator.Send
,而不是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);
}
}
接下来,制作Report.Send
internal,这样它就不是公共API的一部分,应用程序可以做到这一点:
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类,则应将其设置为对USBCommunicator
私有,并将其属性按如下方式推送到通信器的界面:
// USBCommunicator
public void Send(int reportID, int timeout, string data) {
Report report = new Report(reportID, timeout, data);
report.Send(this.stream);
}
由于USBCommunicator
管理所有重要资源(包括流的生存期),应用程序应该调用USBCommunicator.Send
,而不是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);
}
}
接下来,制作Report.Send
internal,这样它就不是公共API的一部分,应用程序可以做到这一点:
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类,则应将其设置为对USBCommunicator
私有,并将其属性按如下方式推送到通信器的界面:
// USBCommunicator
public void Send(int reportID, int timeout, string data) {
Report report = new Report(reportID, timeout, data);
report.Send(this.stream);
}
这不是违反了面向对象的准则吗?如果父类尊重封装,那么就不是了,因为您将使用访问方法来获取所需的信息。这只是一个类引用了另一个类,这不是违反了面向对象的指导原则吗?如果您的父类尊重封装,那么就不是了,因为您将使用访问方法来获取所需的信息。它只是一个引用另一个类的类,那么我的report类位于何处,是什么阻止HighLevelApplication执行此reportToSend=new report()?这将是不好的,因为它没有流,对吗?报表是抽象的,没有实现Send,因此在继承报表并在其他地方实现Send之前,您将无法对其执行任何操作。那么我的报表类位于何处?是什么阻止HighLevelApplication执行此报表报表