Two questions about OOP
BlitzMax Forums/BlitzMax Beginners Area/Two questions about OOP
| ||
Type GraphicalObject
Field x:Float
Field y:Float
Method Draw(off_x:Float = 0, off_y:Float = 0) Abstract
EndType
Type Circle Extends GraphicalObject
Field r:Float
Method Draw(off_x:Float = 0, off_y:Float = 0)
DrawOval (x+off_x, y+off_y, r, r)
EndMethod
EndType
Type Box Extends GraphicalObject
Field w:Float
Field h:Float
Method Draw(off_x:Float = 0, off_y:Float = 0)
DrawRect(x+off_x, y+off_y, w, h)
EndMethod
EndType
Type Text Extends GraphicalObject
Field text:String
Method Draw(off_x:Float = 0, off_y:Float = 0)
DrawText( text, x+off_x, y+off_y)
EndMethod
EndType
Graphics 640,480
HideMouse
t1:Circle = New Circle
t1.x = 20
t1.y = 100
t1.r = 20
t2:Circle = New Circle
t2.x = 120
t2.y = 100
t2.r = 20
t3:Box = New Box
t3.x = 0
t3.y = 60
t3.w = 60
t3.h = 20
t4:Box = New Box
t4.x = 100
t4.y = 60
t4.w = 60
t4.h = 20
t5:Text = New Text
t5.x = 00
t5.y = 20
t5.text = "This is a Test"
While Not KeyHit(KEY_ESCAPE)
Cls
t1.Draw()
t2.Draw()
t3.Draw()
t4.Draw()
t5.Draw()
Flip
Wend
This piece of code is taken from Kurator, OOP: Polymorphism for beginners. If you can, help me. In type graphical object, why only method 'draw' is marked abstract? After all whole type is inherited (Is that correct expression?). For example fields x and y are inherited to type circle. My logic say that type graphical object should be like this: 'Type GraphicalObject abstract.' I tried it and it works. And a other question: Why there is method 'Draw(off_x:Float = 0, off_y:Float = 0) Abstract' in type 'GraphicalObject'? Every extended type has 'draw' method of their own. Sorry about my bad English . It isn't my mother language. Last edited 2010 Last edited 2010 Last edited 2010 |
| ||
| As soon as a Method becomes Abstract the whole Type becomes Abstract. Therefore GraphicalObject is Abstract and there cannot be an instance (new object) created from it. Defining a Method Abstract means the Extended Type has to implent such a Method itself (your Circle, Box, etc all have to implent their own Draw(..) Method). Forcing an Extended Type to have it's own Draw(..) Method is because every Extended Type has another Drawing Routine( DrawCircle, DrawRect, DrawImage, etc ). When not defining a Method Abstract, the Extended Types can use the Methods from the Extended Type (and don't have to implent their own). In your Example the GraphicalObject is abstract due to its Abstract Method Draw(..). You can still define the GraphicalObject Abstract (that would be to help yourself when reading code and immediately see that this Type is Abstract). Hope that helps a bit :D Last edited 2010 |
| ||
| Thanks a lot. I had to use my dictionary but I think I understood what you ment. |
| ||
| Sorry about that, I'll try to explain it with simpler words next time -.- |
| ||
| The reason you have a draw in GraphicalObject, which is empty, is so that you can put boxes, circles and texts into a list or array of GraphicalObject, and tell them to draw without knowing exactly what kind of GraphicalObject they are. Anything which extends from GraphicalObject, will also take on its fields and methods. That's why you have x and y in GraphicalObject, to represent its position on the screen. Rather than setting up all the parameters of the object in loose code, you can tidy them up in Create methods. This shows a more feature-rich and expandable example. Set a DebugStop at the beginning of the code, and go through line by line to see how it works. Type GraphicalObject
Field x:Float
Field y:Float
Field r:Int, g:Int, b:Int
Field a:Float
'all graphical objects automatically set their colour and alpha
Method Draw(off_x:Float = 0, off_y:Float = 0) Final
SetColor r, g, b
SetAlpha a
'we also manage the offset here too
SubDraw(x + off_x, y + off_y)
SetColor 255, 255, 255
SetAlpha 1.0
End Method
'once the colour and alpha is set up, what to actually draw is up to them
Method SubDraw(x:Float, y:Float) Abstract
Method CreateMain:GraphicalObject(nx:Float, ny:Float, nr:Int, ng:Int, nb:Int, na:Float)
x = nx 'x co-ordinate
y = ny 'y co-ordinate
r = nr 'red
g = ng 'green
b = nb 'blue
a = na 'alpha transparency
Return Self
End Method
EndType
Type Circle Extends GraphicalObject
Field r:Float
Method SubDraw(x:Float, y:Float)
DrawOval (x, y, r, r)
EndMethod
Method Create:circle(nr:Float)
r = nr 'radius
Return Self
End Method
EndType
Type Box Extends GraphicalObject
Field w:Float
Field h:Float
Method SubDraw(x:Float, y:Float)
DrawRect(x, y, w, h)
EndMethod
Method Create:Box(nw:Float, nh:Float)
w = nw 'width
h = nh 'height
Return Self
End Method
EndType
Type Text Extends GraphicalObject
Field text:String
Method SubDraw(x:Float, y:Float)
DrawText( Text, x, y)
EndMethod
Method Create:Text(ntext:String)
Text = ntext 'text to display
Return Self
End Method
EndType
Graphics 640,480
'this is needed to turn ON alpha transparency
SetBlend(ALPHABLEND)
HideMouse
'we can store all objects to draw in one list
Local gobjects:TList = New TList
'we use both the CreateMain to set up position, colour and transparency
'and the unique Create method to set up parameters for each type of object
gobjects.AddLast(New Box.Create(60, 20).CreateMain(0, 60, 0, 255, 255, 1.0))
gobjects.AddLast(New Box.Create(60, 20).CreateMain(100, 60, 0, 0, 255, 1.0))
gobjects.AddLast(New Circle.Create(20).CreateMain(20, 70, 255, 0, 0, 0.5))
gobjects.AddLast(New Circle.Create(20).CreateMain(120, 70, 255, 0, 0, 0.5))
gobjects.AddLast(New Text.Create("This is a test").CreateMain(0, 20, 255, 255, 0, 1.0))
While Not KeyHit(KEY_ESCAPE)
Cls
'although it takes a bit more work to set up, look how easy it is
'to draw through all our objects. they could be circles, swords, castles
'cars, planes, monsters, aliens, who cares! they can be drawn all like this
For Local g:GraphicalObject = EachIn gobjects
g.Draw()
Next
Flip
WendLast edited 2010 |
| ||
| "As soon as a Method becomes Abstract the whole Type becomes Abstract." I have to disagree about that. if you put sub1 in class1 abstract there comes a compile error because sub-type Class2 has not method "sub1". But now, when sub1 is not marked as abstract, program doesn't have compile-error. So whole type is'nt abstract because sub1 is not abstract. I hope you understand what I mean. SuperStrict Type Class1 Field x:Int Field y:Int Field z:Int Method sub1() End Method Method sub2() Abstract Method sub3() Abstract End Type Type Class2 Extends Class1 'Method sub1() 'End Method Method sub2() End Method Method sub3() End Method End Type Local blah:Class2=New Class2 blah.x=10 blah.y=10 blah.z=10 blah.sub1() blah.sub2() blah.sub3() |
| ||
a type with an abstract method or function in it forces the type to not be able to be instantiated as an independent type. That is, you can't do this:type class1 method c1(n:int) abstract method c2(d:int) end method end type local ex:class1 = new class1 if you try to run the above code you will get an error because of the abstract method included in the type. the only way for it to work is to attach it to a type and include the proper declaration of the abstract method in the extended type. such as:
type class1
method c1(n:int) abstract
method c2(d:int)
end method
end type
type class2 extends class1
method c1(n:int)
print n
end method
end type
local ex:class2 = new class2
ex.c2()
in the above code the class1 can't be instantiated but the class2 can and class two can use the method c2 that is in class 1. In essense class1 type can be considered as abstract. |
| ||
| But in class1 you don't call method c2 abstract so you can write program like that, don't using method c2 in Class2. Did I understand something wrong? Edit: I looked your code again and now I understand what you ment. It's weird to play with methods in oop world because I don't understand everything yet. For eexample what sentence "Final" do? Last edited 2010 |
| ||
| But you can't make an instance of class1 so that would make it useless by itself. |
| ||
| I wouldn't call it useless if it has fields and methods what class2 uses. |
| ||
| you edited the code and threw the conversation off sense I didn't read it. what I meant is that it's useless if you never create an extention for it. Last edited 2010 |
| ||
| Ok I see what you mean. |
| ||
of course you know that the whole type can be declared as abstract even if it does not have a single abstract function or method. right?:type mytype abstract method c1() end method method c2() end method end type this type can only be instantiated through an extension. Last edited 2010 |
| ||
| For eexample what sentence "Final" do? It prevents any classes(types) inheriting from this class(type). |
| ||
| Thanks a lot! |
| ||
| What means sentence "super"? |
| ||
that's how to access fields, methods and functions in the parent type from the extended type with the same name that exist in both types.
type entity
field x:int
method foo()
.
end method
end type
type myType extendes entity
field x:int
method foo()
super.x = 25 ' assigns 25 to the x in the parent type
super.foo() ' calls the method in the parent type
end method
end type
if super is not included for "super.foo()" then foo will call itself instead of calling the foo in the parent. |
| ||
Type TDog Method identify() Print "I am a dog" End Method End Type Type TDalmation Extends TDog Method identify() Super.identify() Print "I am a dalmation" End Method End Type Type TGreyhound extends TDog Method identify() Super.identify() Print "I am a greyhound" End Method End Type New TDalmation.identify() New TGreyhound.identify() I am a dog I am a dalmation I am a dog I am a greyhound |