如何调用保护成员?

hjcrf 2009-05-18 04:52:38
基类:
TBsPlugin = class(TObject)
private
...
protected
...
procedure ShowM(Sender: TObject); virtual;
...
public
...
published
...
end;

子类有很多 都是从这个基类派生的。eg:
TPluginOne = class(TBsPlugin)
private
...
protected
...
procedure ShowM(Sender: TObject); virtual; {关键的在这里实现}
...
public
...
published
...
end;
现在问题出来了 在主窗口调用不到保护成员ShowM的过程。eg:
var
ss: TPluginOne;
{用的TComponentClass然后动态创建的不一定是TPluginOne,但基类都是TBsPlugin}
begin
ss:=TPluginOne.Create(Self);
ss.ShowM(nil); //提示错误 调用不到ShowM怎么半?
end;

在不修改ShowM到公共成员的情况下如何调用该方法?
因为基于该基类的太多了,改到公共成员会累死人啊。



...全文
227 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjcrf 2009-05-18
  • 打赏
  • 举报
回复
哦~ 我错了错在:
type
TPluginClass = class of TBSPlugin;

这样肯定是不行的 不是他的子类了
谢谢大家了
Harryfin 2009-05-18
  • 打赏
  • 举报
回复
原理就是利用继承能访问protected,和同一单元的类互为友元这两点。
Harryfin 2009-05-18
  • 打赏
  • 举报
回复
我这里完全没问题,不知道你那里是怎样了。


unit Unit4;

interface

uses
Dialogs;

type
tbs = class(TObject)
protected
procedure show;
end;

tone = class(tbs)
protected
end;

implementation

{ tbs }

procedure tbs.show;
begin
ShowMessage('s');
end;

end.



unit Unit3;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Unit4, RzButton;

type
TForm3 = class(TForm)
RzButton1: TRzButton;
procedure RzButton1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form3: TForm3;

implementation

{$R *.dfm}

type
THack = class(tbs);

procedure TForm3.RzButton1Click(Sender: TObject);
var
a: tone;
begin
a := tone.Create;
THack(a).show; //显示s
a.Free;
end;

end.

hjcrf 2009-05-18
  • 打赏
  • 举报
回复
刚试了下 代码写在同一单元就可以访问私有成员,而不在同一单元就不能访问私有成员。

hjcrf 2009-05-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 Harryfin 的回复:]
你先把子类的virtual改成override,不然能调也会出错。

另外应该不会不行,我今天才用过这种用法。请再检查下是否有写错的地方呢
[/Quote]

子类是override我发贴输错的。我以前也用的是可以的(这样相当是享有子类的访问权)但今天就没试成 代码有点多整的晕头可能 呵呵 就是调用不到protected保护成员 试个几个到public才可以。

我在整下试试
Harryfin 2009-05-18
  • 打赏
  • 举报
回复
你先把子类的virtual改成override,不然能调也会出错。

另外应该不会不行,我今天才用过这种用法。请再检查下是否有写错的地方呢
hjcrf 2009-05-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 Harryfin 的回复:]
在要调用的单元,这样写:

Delphi(Pascal) code
type
THackBsPlugin = class(TBsPlugin);
调用:
var
a: TPluginOne;
begin
a := TPluginOne.Create;
THackBsPlugin(a).ShowM(xxx);
a.Free;
end;

但是个人非常不推荐这种用法,新人没搞明白的话会很容易弄糊涂,也有违面向对象的特性。只在特殊情况下才考虑这种写法。
[/Quote]
想过但还是不行
THackBsPlugin(a).ShowM(xxx); //提示:Undeclared identifier: 'ShowM'
Harryfin 2009-05-18
  • 打赏
  • 举报
回复
另外TPluginOne中的ShowM应该声明成override吧
hjcrf 2009-05-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 bdmh 的回复:]
把基类的ShowM放到public中,然后声明变量时,
var
ss: TBsPlugin ;
创建时,比如创建TPluginOne类
ss := TPluginOne.Create;
调用
ss.ShowM(Self);这里将调用TPluginOne.ShowM
[/Quote]
如果不改到公共成员public中有没有其他方法?
TtmpPlugin = class(TBsPlugin)
private
protected
public
procedure ShowM(Sender: TObject); virtual;
published
end;
procedure TtmpPlugin.ShowM(Sender: TObject);
begin
inherited;
end;

但:
var
ss: TComponent;
begin
ss:=TComponent(ComponentClass[i].Create(Self)); {运行会出错}
ss.ShowM(nil);
end;
ComponentClass[i] 因为TPluginOne TPluginTwo ... 等我放到TComponentList 列表里了

怎么写?说个个思路也行(不想改TPluginOne TPluginTwo ..N 个的ShowM到public)

Harryfin 2009-05-18
  • 打赏
  • 举报
回复
在要调用的单元,这样写:


type
THackBsPlugin = class(TBsPlugin);

调用:

var
a: TPluginOne;
begin
a := TPluginOne.Create;
THackBsPlugin(a).ShowM(xxx);
a.Free;
end;


但是个人非常不推荐这种用法,新人没搞明白的话会很容易弄糊涂,也有违面向对象的特性。只在特殊情况下才考虑这种写法。
bdmh 2009-05-18
  • 打赏
  • 举报
回复
把基类的ShowM放到public中,然后声明变量时,
var
ss: TBsPlugin ;
创建时,比如创建TPluginOne类
ss := TPluginOne.Create;
调用
ss.ShowM(Self);这里将调用TPluginOne.ShowM

5,931

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧