Java Delphi类引用

时间:2015-07-17 16:13:12

标签: java delphi

在Delphi中有所谓的类引用:

type
  TSomeClass = class(TAncestorClass)
  .
  .
end;
// They are declared with some weird syntax: (I know Java has no type declarations)
type   
 TSomeClassReference = class Of TSomeClass;  

陈述这样的声明,它可以用作参数

// you can pass TSomeClassReference or any descendant class this function
function ClassFactory (pClassToCreate : TSomeClassReference) : TSomeClass;

// invoke with  
var
A : TSomeClass;  
B : TSomeClassDerivedFromTSomeClass;  

A := ClassFactory (TSomeClass);
B := ClassFactory (TSomeClassDerivedFromTSomeClass);
B := ClassFactory (TAnotherClass); // wrong!

或实例变量

TAnotherClass = class(TAnyClassNotDerivedFromTSomeClass)
  .
  .
  // same: can hold reference to TSomeClass or any descendant
  FDriverClass : TSomeClassReference;
end;  

var  
  A : TAnotherClass;  

  A.FDriverClass := TSomeClass;  
  A.FDriverClass := TSomeClassDerivedFromTSomeClass;  
  A.FDriverClass := TAnotherClass;   // wrong!  

我在Delphi中大量使用这样的类引用来创建类工厂。这样做是否有Java语法?我的意思是

public TSomeClass ClassFactory (pClassToCreate TSomeClassReference) 
{...}

public class TAnotherClass extends TAnyClass { 
   TSomeClassReference FDriverClass;
}

2 个答案:

答案 0 :(得分:4)

在Java 7中,您可以通过将.class添加到类名来获取类引用。

e.g。

Class<Integer> iClass = Integer.class

但是,如果您想使用工厂,建议您在Java 8中使用Supplier,因为这样更灵活。

Supplier<Integer> iSupplier = () -> new Integer(0);
Integer i = iSupplier.get();

答案 1 :(得分:1)

在Java中Class相当于Delphi中的TClass。 Java Object类有getClass()方法返回特定对象实例的类,类似于Delphi的TObjectClassType方法

public final Class<?> getClass() // Java

function ClassType: TClass; // Delphi

例如,String.class的类型为Class<String>

获得相当于声明为

的Delphi元类TSomeClassReference
  TSomeClassReference = class Of TSomeClass;

在Java中,您可以在Class<T>

上使用upper bounded wildcard
  Class<? extends SomeClass>

这将为您提供与Delphi相同的编译时类型检查。

以下示例演示了Java中的简单对象工厂

public class BaseClass
{
    public int b = 0;

    public BaseClass()
    {
        b = 10;
    }
}

public class ClassA extends BaseClass
{
    public ClassA()
    {
        b = 20;
    }
}

public class ClassAA extends ClassA
{
    public ClassAA()
    {
        b = 22;
    }
}

public class ClassB extends BaseClass
{
    public ClassB()
    {
        b = 30;
    }
}

public class BaseFactory 
{
    public static BaseClass create(Class<? extends BaseClass> clazz)
    {
        try
        {
            return clazz.getConstructor().newInstance();
        }
        catch (NoSuchMethodException e)
        {
            e.printStackTrace();
        }
        catch (InvocationTargetException e)
        {
            e.printStackTrace();
        }
        catch (InstantiationException e)
        {
            e.printStackTrace();
        }
        catch (IllegalAccessException e)
        {
            e.printStackTrace();
        }
        return null;
    }
}

然后您可以使用工厂创建像

这样的对象
Class<? extends BaseClass> c = ClassA.class;
BaseClass o = BaseFactory.create(c);

BaseClass o = BaseFactory.create(BaseClass.class);
BaseClass o = BaseFactory.create(ClassA.class);
BaseClass o = BaseFactory.create(ClassAA.class);
BaseClass o = BaseFactory.create(ClassB.class);

Class<? extends BaseClass> c = String.class; // this will not compile
BaseClass o = BaseFactory.create(String.class); // this will not compile

Delphi中的等效对象工厂 - 类型名称已更改为符合Delphi编码样式。

BaseClass - TBaseObject

ClassA - TObjectA

Class<? extends BaseClass> - TBaseClass

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes;

type
  TBaseObject = class(TObject)
  public
    b: integer;
    constructor Create; virtual;
  end;

  TBaseClass = class of TBaseObject;

  TObjectA = class(TBaseObject)
  public
    constructor Create; override;
  end;

constructor TBaseObject.Create;
begin
  inherited;
  b := 10;
end;

constructor TObjectA.Create;
begin
  inherited;
  b := 20;
end;

function BaseFactory(clazz: TBaseClass): TBaseObject;
begin
  Result := clazz.Create;
end;

var
  o: TBaseObject;
  c: TBaseClass;
begin
  o := BaseFactory(TBaseObject);
  writeln(o.b); // 10
  o.Free;

  o := BaseFactory(TObjectA);
  writeln(o.b); // 20
  o.Free;

  c := TObjectA;
  o := BaseFactory(c);
  writeln(o.b); // 20
  o.Free;

  readln;
end.