Abstract Classes (Types)

BlitzMax Forums/BlitzMax Programming/Abstract Classes (Types)

Yue(Posted 2016) [#1]
What is the purpose of abstract classes?

Since you can not create instances of those classes, your goal would be to write less code? Since in the abstract class you define certain variable fields that will have their child classes.

For example :


Type TAnimal Abstract

      field legs:int
      field alive:int

End Type 


Type TCat extends TAnimal

          function Init_TCat:TCat()

               Local cat:TCat  = New Tcat

                  self.alive:int = true
                  self.legs:int  = 4
                
               Return cat:TCat  

          End Type 
        

End Type extends TAnimal


Type Tbird Extends TAnimal


          function Init_TBird:TBird()

               Local bird:TBird  = New TBird

                  self.alive:int = true
                  self.legs:int  = 2
                
               Return bird:TBird  

          End Type 

End Type 


local catWhite:TCat  = TCat.Init_TCat()
local birdBlue:TBird  = TBird.Init_TBird()






I am right?

If this is how you can implement abstract methods in the abstract class then instantiate it in the child class.


TomToad(Posted 2016) [#2]
Seems like I've answered this one before.

http://www.blitzbasic.com/Community/post.php?topic=105198&post=1280082


Jesse(Posted 2016) [#3]
See if this helps with your own code:
Type TAnimal Abstract

      Field legs:Int
      Field alive:Int

	  Method Draw() Abstract *****************
End Type 


Type TCat Extends TAnimal

          Function Init:TCat()

               Local cat:TCat  = New Tcat

                  cat.alive:Int = True
                  cat.legs:Int  = 4
                
               Return cat  

          End Function

		Method Draw() '****** Must match the abstract method in TAnimal
			Print "cat Legs: "+ legs
		End Method

End Type

Type Tbird Extends TAnimal


          Function Init:TBird()

               Local bird:TBird  = New TBird
				   
                  bird.alive:Int = True
                  bird.legs:Int  = 2
                
               Return bird  

          End Function 

		Method Draw() ' ****** Must match the abstract method in TAnimal
			Print "bird Legs: "+legs
		End Method
		
End Type 

Local list:TList = New TList

list.AddLast(Tbird.Init())
list.AddLast(Tcat.Init())

For Local animal:Tanimal = EachIn list '***** declared as abstract animal
	animal.Draw()
Next 




Yue(Posted 2016) [#4]
@Jesse
Thanks You, Simple examples help me understand all this.


Now, one more question, what does Super ?, What does Final?


Derron(Posted 2016) [#5]
Super :

Type TBase
  Method MyName:string()
    return "Base"
  End Method
End Type

Type TExt extends TBase
  Method MyName:string()
    'return Super.MyName()
    return "TExt"
  End Method
End Type

local ext:Text = new TExt
print ext.MyName()


Super refers to the parent of the type. So the one it extends from.


Final: does not allow extensions


bye
Ron


Jesse(Posted 2016) [#6]
Final used to prevent a type from being extended.

Super:
Type TAnimal Abstract ' this is not required if there is an abstract method in the Type.

      Field legs:Int
      Field alive:Int
	  Field name:String '*******************

	  Method Draw()
		Print name+" Legs: "+legs
	  End Method
End Type 


Type TCat Extends TAnimal

          Function Init:TCat() 
               Local cat:TCat  = New Tcat
                  cat.alive:Int = True
                  cat.legs:Int  = 4
                  cat.name = "cat" '*************
               Return cat  

          End Function

		Method Draw()
			Super.Draw() 'use the base Draw()
		End Method

End Type

Type Tbird Extends TAnimal


          Function Init:TBird()
               Local bird:TBird  = New TBird
                  bird.alive:Int = True
                  bird.legs:Int  = 2
				  bird.name = "bird" '***********
               Return bird  
          End Function

		Method Draw()
			Super.Draw() '******************* use the base Draw() ************************
		End Method
		
End Type 

Local list:TList = New TList

list.AddLast(Tbird.Init())
list.AddLast(Tcat.Init())

For Local animal:Tanimal = EachIn list
	animal.Draw()
Next 



Yue(Posted 2016) [#7]
Thank you all.


Now to finish my questionnaire.

I have two more questions: What do you do privately ?, What do you do public ?. Yasha a while ago I try to explain it, but I can not fully grasp it. When I see those two words, I immediately think of C #, but I can not fully understand BlitzMax. Is it used to encapsulate data within Types?

Private
Public





TomToad(Posted 2016) [#8]
Private keeps a programmer from accessing certain fields and methods in a Type. This is so that if the developer of a module should change the implementation of a Method, it wont break existing code.

For example, suppose you have a type in your module like so

Now someone can create a rectangle by defining its corners, and call Draw to draw it
Local Rect:TRect = TRect.Create(10,10,500,300) 'Draws a rectangle from 10,10 to 500,300
Rect.Draw 'Draws the rectangle


but there is a bug. if x2 or y2 is smaller than x1 or y1 then you have unpredictable results. So you decide to have the coordinates checked when creating the rectangle and modify the code like so.

That fixes the order bug, and it wont interfere with existing code as the function calls have not changed.

But suppose that the programmer decides to access the fields directly
'Case 1
Local Rect:TRect = New TRect
Rect.x1 = 10
Rect.x2 = 500
Rect.y1 = 300
Rect.y2 = 10
Rect.Draw

'Case 2
Local Rect:Trect = TRect.Create(500,300,10,10)
Local x1:Int = Rect.x1
Local y1:int = Rect.y1

In case 1, the checks were bypassed completely. In case 2, the values you retrieve might be different from what you entered (500 was entered in the x1 parameter of TRect.Create function, but was assigned to field x2) and they will blame you for their program not working.

By using Private on those fields you don't want accessed, you prevent such a thing from happening, forcing the programmer to only use the interfaces you want them to use. Like so



Brucey(Posted 2016) [#9]
I should add that TomToads example only applies to BlitzMaxNG, as the classic version doesn't support Private in Types.

I personally think it adds a lot to the language though.


Yue(Posted 2016) [#10]
@TomToad Thanks You.
Error here:




Jesse(Posted 2016) [#11]
Read Brucey's post
Type TRect
	Private
	Field x1:Int, y1:Int, x2:Int, y2:Int
	
	Public
	Function Create:TRect(x1:Int,y1:Int,x2:Int,y2:Int)
		Local Rect:Trect = New TRect
		If x2 < x1
			Rect.x1 = x2
			Rect.x2 = x1
		Else
			Rect.x1 = x1
			rect.x2 = x2
		End If
		If y2 < y1
			Rect.y1 = y2
			Rect.y2 = y1
		Else
			Rect.y1 = y1
			Rect.y2 = y2
		End If
		Return Rect
	End Function
	
	Method Draw()
		DrawRect x1,y1,x2-x1,y2-y1
	End Method
End Type



Yue(Posted 2016) [#12]
@Jesse No work.

Edit: oppps!,
Skipped the Brucy Post, it only works in BlitzMax NG, I need to know how to use it in Classic BlitzMax.


TomToad(Posted 2016) [#13]
I should add that TomToads example only applies to BlitzMaxNG, as the classic version doesn't support Private in Types.



Would've sworn it could also be used in Types. Guess I was wrong. Seems it can only be used in modules and Includes outside of types which really limits its usefulness.


Yue(Posted 2016) [#14]
Now, include vs import.

What dramatic difference is there?


Yue(Posted 2016) [#15]
Now, include vs import.

What dramatic difference is there?


Ole JR(Posted 2016) [#16]
Include vs Import:
http://www.blitzbasic.com/Community/posts.php?topic=103748#1251952