Delphi 如何访问子类中的函数?

Delphi 如何访问子类中的函数?,delphi,oop,inheritance,class,Delphi,Oop,Inheritance,Class,子类可以访问父类中的受保护函数,但父类不能访问子类中的受保护函数 我希望两个类都尽可能私有。父类是一个窗体,只使用一次实例。子类中的所有函数都是静态的,它从父类继承 如何从父类访问子类(在另一个单元中)中的非公共静态方法 编辑: 父级(第一单元): 儿童班(第二单元): 代码(第三单元): 输出只是“初始化”。我试图调试它,但它没有到达子类。这是不可能的。在子类中使用非公共方法的全部目的是防止类(子类除外)能够访问它们。试图解决这个问题违反了基本的面向对象原则 我会考虑重新考虑一下你的设计。<

子类可以访问父类中的受保护函数,但父类不能访问子类中的受保护函数

我希望两个类都尽可能私有。父类是一个窗体,只使用一次实例。子类中的所有函数都是静态的,它从父类继承

如何从父类访问子类(在另一个单元中)中的非公共静态方法

编辑:

父级(第一单元):

儿童班(第二单元):

代码(第三单元):


输出只是“初始化”。我试图调试它,但它没有到达子类。

这是不可能的。在子类中使用非公共方法的全部目的是防止类(子类除外)能够访问它们。试图解决这个问题违反了基本的面向对象原则


我会考虑重新考虑一下你的设计。< / P > >这是不可能做到的。在子类中使用非公共方法的全部目的是防止类(子类除外)能够访问它们。试图解决这个问题违反了基本的面向对象原则


我会考虑重新考虑你的设计。

< P>你想做的违背继承的原则。也许有更好的方法。你到底想做什么

编辑:


为什么不能从子类创建对象实例。您始终可以将其分配给父类类型的变量。这通常是在工厂模式中完成的。

您想要执行的操作违反了继承中的原则。也许有更好的方法。你到底想做什么

编辑:


为什么不能从子类创建对象实例。您始终可以将其分配给父类类型的变量。这通常在工厂模式中完成。

您可以通过在创建子类时使用某种回调(父类上的cattr,定义子类时设置子类)向父类注册子类来完成

不过,这样做很少是正确的。就像其他人所说的,考虑不同的模式。

我不是delphi程序员,但您可以在父类上设置公共静态变量,并从子类中的setup方法设置它


这在某些情况下是有意义的(希望将消息传递给各种子类上的类设置方法),但是可能有更好的方法来完成您需要的任务。您可能想让您的问题更多地与您的代码正在解决的问题有关。

您可以通过在创建子类时向父类注册子类,并使用某种回调(父类上的cattr,定义子类时子类集)来实现这一点

不过,这样做很少是正确的。就像其他人所说的,考虑不同的模式。

我不是delphi程序员,但您可以在父类上设置公共静态变量,并从子类中的setup方法设置它


这在某些情况下是有意义的(希望将消息传递给各种子类上的类设置方法),但是可能有更好的方法来完成您需要的任务。您可能想让您的问题更多地与您的代码正在解决的问题有关。

实际上有几种方法可以做到这一点,在您的父类中,创建您调用的虚拟方法,但这些方法不起任何作用。在子类中,重写这些方法。这些方法可以很容易地得到保护,但它们必须存在于父级中

type
  TParent = class
  protected
    procedure SpecialProcessing; virtual;
  public
    procedure DoWork;
  end;

  TChild = class(TParent)
  protected
    procedure SpecialProcessing; override;
  end;

procedure TParent.DoWork;
begin
  SpecialProcessing;
end;

procedure TParent.SpecialProcessing;
begin
  // does nothing, placeholder
end;

procedure TChild.SpecialProcessing;
begin
  // do special work here
end;
我故意不做TParent.SpecialProcessing摘要。这是可以做到的,但前提是TParent永远不会直接创建,只有Decentant才会创建。抽象方法是未实现的方法,但作为占位符供后续子级实现

要创建实例,请使用以下命令:

var
  C : TParent;
begin
  // Create as a TChild, which is a TParent decendant
  C := TChild.Create;
  try
    C.DoWork;
  finally
    C.Free;
  end;
end;

实际上有几种方法可以做到这一点,在父类中,创建您调用的虚拟方法,但这些方法不起任何作用。在子类中,重写这些方法。这些方法可以很容易地得到保护,但它们必须存在于父级中

type
  TParent = class
  protected
    procedure SpecialProcessing; virtual;
  public
    procedure DoWork;
  end;

  TChild = class(TParent)
  protected
    procedure SpecialProcessing; override;
  end;

procedure TParent.DoWork;
begin
  SpecialProcessing;
end;

procedure TParent.SpecialProcessing;
begin
  // does nothing, placeholder
end;

procedure TChild.SpecialProcessing;
begin
  // do special work here
end;
我故意不做TParent.SpecialProcessing摘要。这是可以做到的,但前提是TParent永远不会直接创建,只有Decentant才会创建。抽象方法是未实现的方法,但作为占位符供后续子级实现

要创建实例,请使用以下命令:

var
  C : TParent;
begin
  // Create as a TChild, which is a TParent decendant
  C := TChild.Create;
  try
    C.DoWork;
  finally
    C.Free;
  end;
end;

我可能遗漏了一些对已经回答的人来说显而易见的东西。但我认为这只是实例化正确对象的问题

如果对象是子类的实例,则父代码将调用子代码

试试这个

var c:TChild;
begin
  c := TChild.Create;
  c.Initialize;
  c.Free;
end.
甚至

var c:TParent;
begin
  c := TChild.Create;
  c.Initialize;
  c.Free;
end.

我可能遗漏了一些对已经回答的人来说显而易见的东西。但我认为这只是实例化正确对象的问题

如果对象是子类的实例,则父代码将调用子代码

试试这个

var c:TChild;
begin
  c := TChild.Create;
  c.Initialize;
  c.Free;
end.
甚至

var c:TParent;
begin
  c := TChild.Create;
  c.Initialize;
  c.Free;
end.

@迈克尔,请出示一些密码,我一个人做不了你说的。谢谢@迈克尔,请出示一些密码,我一个人做不了你说的。谢谢!斯卡姆拉特,首先感谢你的回答!我更喜欢第一种方法,我试着去实现它,但是魔法没有起作用。请再次检查我的问题,我为youskamradt做了编辑,首先感谢你的回答!我更喜欢第一种方法,我试着去实现它,但是魔法没有起作用。请再次检查我的问题,我为你做了一次编辑,它从未到达子类,因为你创建的类是错误的。将create更改为C:=TChild.create,它就会工作。您正在错误地实例化该类。我想你以前听说过这件事。当您调用
c.Create
时,编译器没有警告您吗?如果你想要c