如何在Dart中模拟受保护的方法?
(在办公室无意中听到,我们认为其他人会受益) 假设我在一个库中有一个基类,它提供了一些基本特性,但它是由库用户派生的 例如,我有一个抽象的问候语类。子类表示特定类型的问候语,如HighFiveGreeting或HugGreeting或其他。Greeting为子类提供了一些实用函数,如如何在Dart中模拟受保护的方法?,dart,Dart,(在办公室无意中听到,我们认为其他人会受益) 假设我在一个库中有一个基类,它提供了一些基本特性,但它是由库用户派生的 例如,我有一个抽象的问候语类。子类表示特定类型的问候语,如HighFiveGreeting或HugGreeting或其他。Greeting为子类提供了一些实用函数,如sendGreeting()。我不希望这些类的用户调用sendGreeting() 可能吗?Dart中有更好的成语来形容这种事情吗 图书馆问候语; 抽象类问候语{ 无效发送问候语(问候事件){…} } libra
sendGreeting()
。我不希望这些类的用户调用sendGreeting()
可能吗?Dart中有更好的成语来形容这种事情吗
图书馆问候语;
抽象类问候语{
无效发送问候语(问候事件){…}
}
library自定义问候语;
导入“greeting.dart”;
类问候语扩展了问候语{
//这里的代码使用sendGreeting()
}
librarymain;
导入“custom_greeting.dart”;
var hug=新的HugGreeting();
拥抱。发送问候语(…);//不应编译
我认为没有办法做到这一点,但是FWIW,这似乎是一种组合比继承更可取的情况:
类问候发送者{
无效发送问候语(问候事件);
}
班级问候语{
问候发送者(u发送者);;
雨果问候语(此。\发送者);
虚空拥抱(){
//使用_sender.sendGreeting()
}
}
每个涉及调用在超类中实现的受保护方法的设计都有相应的设计,其中超类由通过构造函数注入的接口替换,我还没有遇到过这样的情况,但这并不能改善情况。你可以利用图书馆作为隐私的边界来做类似的事情,比如:
图书馆问候语;
抽象类问候语{
void _sendGreeting(字符串问候语)=>打印(问候语);
}
类问候语扩展了问候语{
void sendHug()=>_sendGreeting(“拥抱”);
}
在主文件中:
导入“问候语.省道”;
拥抱问候拥抱=新的拥抱问候();
hug.sendHug();
这样,只有从
Greeting
扩展并驻留在同一库中的类才能访问低级\u sendGreeting()
方法。为什么不使用几乎标准的前缀将函数标记为private或protected
我认为您不应该完全阻止对私有或受保护函数的访问。当然,让用户知道不需要访问,但不应该阻止它。就在今天,我在dart sdk中发现了一个bug。我本可以重写错误的函数并仍然使用类的其余部分,但该类被标记为private。。。我需要将类复制回我的应用程序中。。。但我在这里很幸运,因为它不依赖于其他任何东西,但我记得我在c#for listview中做了类似的事情,我最终用数百个私有类重新创建了完整的库,只是为了做一个小小的改变
图书馆问候语;
抽象类问候语{
void_sendGreeting(GreetingEvent事件){…}
}
library自定义问候语;
导入“greeting.dart”;
类问候语扩展了问候语{
//这里的代码使用_sendGreeting()
}
librarymain;
导入“custom_greeting.dart”;
var hug=新的HugGreeting();
拥抱。_发送问候语(…);//应该编译,可能有警告。。。
我也遇到了同样的问题,但有人提出了以下解决方案,这对我很有效。我将用一个简短的例子来演示:
库视图;
抽象类视图{
工厂视图({HtmleElement host})=ViewImpl;
void enable(){}
}
类ViewImpl实现视图{
HtmlElement主机;
ViewImpl({this.host});
@凌驾
void enable(){
host.classes.remove('disabled');
}
}
在另一个图书馆:
库按钮;//注意,这是另一个图书馆
抽象类按钮扩展视图{
工厂按钮({String title,HtmlElement host})=ButtonImpl;//神奇就发生在这里!
}
类ButtonImpl扩展ViewImpl实现按钮{
字符串标题;//瞧,一个受保护的属性
ButtonImpl({this.title,HtmlElement主机}):超级(主机:主机);
}
您可以这样使用它:
final按钮=新按钮(标题:“取消”,主机:元素);
button.title/=>无法访问!
此外,您还可以在单元测试中访问受保护字段:
//实例化*Impl类以绕过保护。
最终按钮=新按钮MPL(标题:“取消”,主机:元素);
expect(button.title,等于(“取消”);//=>它可以工作!
简而言之,您可以在Impl类中隐藏“受保护”的方法。您可以在不同的库中自由扩展实现
希望这会有所帮助。这将调用方限制在子类以及所有可以访问这些子类的私有成员的对象上 **图书馆问候语
类问候事件{
最后信息;
问候事件(this.message);
toString()=>消息;
}
抽象类问候语{
//子类必须将方法传递给超级构造函数
//它允许在子类中设置私有字段。
问候语(功能设置受保护){
//传递“this”,以便传递的静态方法具有实例
//上下文
setProtected(this,new GreetingProtected(this));
}
//保护
void\u sendGreeting(问候事件){
印刷(活动);
}
}
//此类提供对受保护成员的访问
//只需转接电话
类迎宾保护{
//保护
最后的问候;
受保护的问候语(本。\问候语);
无效发送问候语(问候事件)=>\u问候语。\u发送问候语(事件);
}
**图书馆定制问候语
library自定义问候语;
导入“greeting.dart”;
类问候语扩展了问候语{
//对
欢迎受保护(u保护);;
//将该方法传递给可以
//分配受保护的转发器
HugGreeting():超级(_setProt