基类:
  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到公共成员的情况下如何调用该方法?
因为基于该基类的太多了,改到公共成员会累死人啊。

解决方案 »

  1.   

    把基类的ShowM放到public中,然后声明变量时,
    var 
      ss: TBsPlugin ; 
    创建时,比如创建TPluginOne类
    ss := TPluginOne.Create;
    调用
    ss.ShowM(Self);这里将调用TPluginOne.ShowM
      

  2.   

    在要调用的单元,这样写:
    type 
      THackBsPlugin = class(TBsPlugin);调用:var
      a: TPluginOne;
    begin
      a := TPluginOne.Create;
      THackBsPlugin(a).ShowM(xxx);
      a.Free;
    end;
    但是个人非常不推荐这种用法,新人没搞明白的话会很容易弄糊涂,也有违面向对象的特性。只在特殊情况下才考虑这种写法。
      

  3.   

    如果不改到公共成员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) 
      

  4.   

    另外TPluginOne中的ShowM应该声明成override吧
      

  5.   

    想过但还是不行
    THackBsPlugin(a).ShowM(xxx); //提示:Undeclared identifier: 'ShowM' 
      

  6.   

    你先把子类的virtual改成override,不然能调也会出错。另外应该不会不行,我今天才用过这种用法。请再检查下是否有写错的地方呢
      

  7.   


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

  8.   

    我这里完全没问题,不知道你那里是怎样了。
    unit Unit4;interfaceuses
      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;interfaceuses
      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.
      

  9.   

    原理就是利用继承能访问protected,和同一单元的类互为友元这两点。
      

  10.   

    哦~ 我错了错在: 
    type
      TPluginClass = class of TBSPlugin;这样肯定是不行的 不是他的子类了 
    谢谢大家了