.edit: misschien moet ik voortaan de rest van de topic doorlezen voordat ik reply

EfBe schreef op 01 May 2003 @ 11:49:
[...]
Maar de float -> int conversie is in feite de upcast van float naar int in het model waar je float van int derived. Wat verlies van info oplevert, je verliest nl. de fraction, wat precies het resultaat is wat jij zegt: wanneer je een float (in het model van float derived van int) doorgeeft aan een functie die een int verwacht (base class van float) zal daar alleen de fraction-less part van de float (heeft ook een naam, kan er even niet opkomen) het gehele getal dus) beschikbaar zijn.
Maar in diezelfde redenering kun je een functie die een Int verwacht ook een Float voeren, en dat is niet de bedoeling
Als ik class Dier heb en ik derive daar de class Hond van, dan kan ik hond wel gebruiken als 'Dier' (het is tenslotte type 'Dier') maar je verliest de eigenschappen van de specifieke class Hond, precies wat je ook hebt wanneer je float van int derived.
maar Hond is een subset van Dier. Net als int een subset van float is. Het is een beetje als het Circle <-> Oval probleem. Circle is dan imho een subclass van Oval, ookal heeft het minder eigenschappen. Eigenlijk heeft het juist restricties, maar die kun je weer niet opgeven in de meeste talen
Dmv implicit cast operators te definieren kun je de downcast bewerkstelligen tussen int en float, zoals dat vaak gedaan wordt. (half .NET zit er vol mee) de upcast van float naar int gaat al goed, je verliest gewoon de fraction.
ja maar het is de bedoeling dat je juist een error cq. warning krijgt als die (impliciete) upcast optreedt. Je hoort een functie die een int verwacht immers niet zomaar een float te kunnen geven
Dat zou dan pleiten voor een class tree zoals Alarmnummer hem nu al heeft: float waar int vanaf derived. Echter, in class-trees gaat het erom dat je bij elke derive specialisatie toevoegt, eigenschappen die het type van het supertype specialiseren in het subtype. Qua eigenschappen bevat een 'float' alle eigenschappen van int en meer, nl. het definieert een fraction, vandaar dat het imho logisch is om float van int te deriven (mocht je uberhaupt daar een class tree van willen maken

)
Je kunt het ook zo zien: de specialisatie van int zorgt ervoor dat het fractational part altijd op 0 komt te staan. In plaats van data toe te voegen zorg je ervoor dat je het bereik van de data verkleind.
In principe zou je een klasse SubInt kunnen maken die alleen integers in het bereik van [0, 10] toe laat. Hier is geen uitbreiding van de data, maar een restrictie op de huidige data. Een functie dat een int accepteert kun je ook een SubInt voeren. Aan een functie dat altijd een int tussen 0 en 10 wilt kun je
geen int geven.
Gaat het bij OO modelling niet om definities van containers waar data in wordt geplaatst? Nu ga je de grenzen van de data die eventueel in de containers wordt geplaatst gebruiken om de class-hierarchie te modelleren, terwijl volgens mij de eigenschappen van de CONTAINERS moeten worden gebruikt voor het modellering van de classes, wat dus een omgekeerde tree tot gevolg heeft.
imho is subclassing bij OO niet specifiek op het toevoegen van data gericht (inheritance). Bovendien zou de data private moeten zijn zodat het niet eens opvraagbaar is. Daar kun je wel weer functies voor maken, maar die kun je overriden in de subclasses.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| interface Float
{
float getIntPart ();
float getFractationalPart ();
}
class FloatImpl implements Float
{
float f;
float getIntPart () { return (int)f; }
float getFloatPart () { return f - (int)f; }
}
interface Int extends Float { }
class IntImpl implements Int
{
int i;
float getIntPart () { return i; }
float getFloatPart () { return 0; }
} |