[fpc-pascal] Question about interfaces and patch
memsom
memsom at interalpha.co.uk
Thu Mar 24 23:41:24 CET 2005
> 1. and what I would like is just a lot cleaner and readable code of
> this.
> 2. Before you tell how to do something at least test and look your
> solution
> 2.1. Because queryinterface doesn't work in fpc as it should you always
> get first vmt and if you do a queryinterface you don't work with correct
> interface, you just get exception when you work with this new interface.
> Anyway patch for this will be finished until weekend.
> 2.2. It's ugly and not really readable, you always land with additional
> declarations like tmp
FPC is wrong. To be Delphi compatible, you need IS to work as well as
QueryInterface. I'm not interested in your suggestion, it's non standard
and will cause a break in compatibility...
> Follow the vmt problems. That is needed for defining blind properties.
> It has to be redirected to original vmt of class.
Absolutely not!!!! Blind properties will break Delphi compatibility.
Also... remember the property you define in the interface is NOT the same
as the one you define in the class. Indeed, you need not defire the
property in the class, or can make the property in the interface readonly,
for example.
> For now you have to specify properties as
>
> type
> IA = interface
> function GetSome: integer;
> procedure SetSome(aValue: integer);
> property Some: integer read GetSome write SetSome;
> end;
>
> this is needed because interface has no clue of original vmt. while
> blind properties definition would be
>
> type
> IA = interface
> property Some: integer read object write object;
> end;
>
> and the implementation of property is left to class, not conditioned
> with function and procedure
This is hideous!! I *WANT* to define the property in the interface. That
is the whole point!!! Otherwise, how can I do this:
type
IA = interface
function GetSome: integer;
property Some: integer read GetSome;
procedure ALittle; //state machine
procedure SomeMore; //some is moved through
procedure ALot; //three states
end;
TA = class(TInterfacedPersistent, IA)
private
function GetSome: integer;
procedure SetSome(aValue: integer);
published
property Some: integer read GetSome write SetSome; //for streaming
end;
Simply, you will not be able to do this in the same way!!! Remember, an
interface is a pure abstract class in reality!!
Another question:
> type
> IA = interface
> property Some: integer read object write object;
> end;
This implies I must have a property called "Some", however, I commonly do
the following:
IA = interface
function GetSome: integer;
procedure SetSome(aValue: integer);
property Some: integer read GetSome;
end;
TA = class(TInterfacedPersistent, IA)
private
function GetSome: integer;
procedure SetSome(aValue: integer);
published
property A1289: integer read GetSome write SetSome; //for streaming
end;
"A1289" is obstificated to hide its meaning within the streaming
mechanism. This used to be important because the company I was working
with had a product, which used an Object persistence mechanism using RTTI,
that we inherited from the products former supplier. We effectively
"forked" the code because the two companies split appart their partnership
in a less than amicable break up of a company releationship. Each company
continued development on the product. We purpousfully obstificated our new
properties to give them no clues on how to interpret our data if they
attempted to take over one of our customer sites. This is purely
political, but also remember that when storing a streamed class, delphi
stored the property name. I'd prefer a meaningful name in my code, e.g.
IPublic.YearlyProfitMargin, but a shorter name in streaming to save room,
i.e. TPrivate.YPM. Does that make sense? If you store 1 of those classes,
the size is negligable. However, store 100000 and the difference is
notable in real disk space.
In truth we would do the following:
TA = class(TInterfacedPersistent, IA)
private
function GetSome: integer;
procedure SetSome(aValue: integer);
public
property INF_some: integer read GetSome write SetSome;
published
property A1289: integer read GetSome write SetSome; //for streaming
end;
How does that fit with your plans??? Not so simple is it? ;-) Dual
properties are perfectly legal. A1289 will NEVER be used in code. It's
there for streaming alone.
> How could you define private class outside where it is not visible. Best
> shot for you it would be highest visible type of this class. So sorry, I
> don't understand this part. This is something which is completely normal
> behavior and is connected to software plan only. No rocket since here.
Read the code. The TPrivate class is controlled by the TFactory. The
TPrivate class is defined in the implementation secton of the unit - it is
PRIVATE to the unit. You access it via the interface IPublic, returned via
the TFactory.newXXX call. You are aware of encapsulation, arent you? Also,
design patterns.
>>
>> How would you be able to get at the class? Only as TObject or
>> TInterfacedObject. Bad idea.
>
> I don't know where the idea here is and thus I don't know why it would
> be bad.
Encapslation. The provate implementation can change, or can be replaced
without code changes. This is just like using inline classes in Java,
really.
Matt
More information about the fpc-pascal
mailing list