Oxygen Basic

Programming => Example Code => Topic started by: Arnold on August 06, 2016, 04:18:55 AM

Title: Starting Oop with OxygenBasic
Post by: Arnold on August 06, 2016, 04:18:55 AM
Hi Charles,

after some vacation and following the many news around the world I sat down to continue my studies with O2h in order not to suffer a depression.

I ran the object-oriented example Hello program in your main homepage. It looks much more OOP than the general "cout << "Hello World" << endl;" and I tried out some variations. At the moment I found this possible way:

Code: OxygenBasic
  1. $filename "Hello.exe"
  2.  
  3. 'include "$/inc/RTL32.inc"
  4. 'include "$/inc/RTL64.inc"
  5.  
  6. % TryAttachConsole
  7. include "$/inc/console.inc"
  8.  
  9. SetConsoleTitle "Say Hello and Goodbye"
  10.  
  11. ' Object-oriented
  12.  class entity
  13.     method greet() as string
  14.     method say_goodbye() as string
  15.     /\
  16.     to_whom as string
  17.     what_prop as string
  18.   end class
  19.  
  20.   '--------------  
  21.  methods of entity
  22.   '================
  23.    
  24.     method greet() as string
  25.         method = "Hello "
  26.         if len what_prop then method += what_prop & " "
  27.         if len to_whom then method += to_whom
  28.     end method
  29.    
  30.     method say_goodbye() as string
  31.         method = "Goodbye "
  32.         if len what_prop then method += what_prop & " "
  33.         if len to_whom then method += to_whom
  34.     end method
  35.      
  36.   end methods
  37.  
  38.   '====
  39.  'TEST
  40.  '====
  41.  
  42.   entity we
  43.   printl we.greet()
  44.   printl we.say_goodbye()
  45.    
  46.   we.to_whom = "World"
  47.   printl we.greet()
  48.   printl we.say_goodbye()
  49.  
  50.   entity I
  51.   I.to_whom = "Susanne"
  52.   I.what_prop = "beautiful"
  53.   printl I.greet()
  54.  
  55.   I.to_whom = "Kate"
  56.   I.what_prop = "cruel"
  57.   printl I.say_goodbye()
  58.    
  59.   printl cr & "Hit Enter ... " : waitkey
  60.  

In the method procedure the &= did not work and I had to use the += operator.

Exploring the many provided examples I can see that there are a lot of ways to do object-oriented programming with OxygenBasic. What would be the easiest and clearest way to get the possible results of the hello example above in Oop?

Roland


.
Title: Re: Starting Oop with OxygenBasic
Post by: JRS on August 06, 2016, 01:57:09 PM
O2

Another example of an outstanding language viewed as to be too good to be true.  :o
Title: Re: Starting Oop - SuperString.o2bas
Post by: Arnold on August 08, 2016, 12:01:57 AM
Hi Charles,

I refer to the demo examples\OOP\SuperString.o2bas. Using the latest Oxygen.dll the line:

print ss.b[3] 'result 99: ascii for 'c'

gives a result of 0, expected is 99. ss.b[1] returns 97 and ss.b[2] returns 98. Using oxygen.dll A40 30/01/2015 shows the expected result. Using a newer oxygen.dll A40 17/03/2015 will again show the result 0.

#recordof Superstring shows different outputs. With the newer dlls the output is:
...
b 4 0 0  39AA, byte
...

the output using the older dll is:
...
b 4 0 0  39A, byte
...

I do not know if ss.b[3] must be retrieved differently now?

BTW in the union the members sys *y and float *f are declared. Is there a special purpose for these declarations or do these members only serve for further use?

Roland
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 08, 2016, 06:22:01 AM
Hello,

this is a translated example which I found coded in Java and it works quite nice with OxygenBasic too.

What method should I use to cancel my_account, assumed my bank will allow this?

Roland

Code: OxygenBasic
  1. $filename "Banking.exe"
  2.  
  3. 'include "$/inc/RTL32.inc"
  4. 'include "$/inc/RTL64.inc"
  5.  
  6. % TryAttachConsole
  7. include "$/inc/console.inc"
  8.  
  9. SetConsoleTitle "Bank Transactions"
  10.  
  11. class account
  12.   ' Attributes
  13.  int account_num
  14.   double balance
  15.  
  16.   method pay_out(double amount)
  17.     balance -= amount
  18.     printl "Payed out: " str(amount) & " Euro"
  19.   end method
  20.  
  21.   method pay_in(double amount)
  22.     balance += amount
  23.     printl "Payed in: " str(amount) & " Euro"
  24.   end method
  25.  
  26.   method statement_of_account()
  27.     printl "Account Number: " & account_num & " Balance: " & str(balance) &" Euro"
  28.   end method
  29.  
  30. end class
  31.  
  32. account my_account ' new instance of type account
  33.  
  34. my_account.account_num = 1234567
  35. my_account.balance = 100.00
  36. printl "Account Number: " & my_account.account_num & " Balance: " & my_account.balance
  37. my_account.pay_out(600.00)
  38. my_account.statement_of_account()
  39. printl()
  40.  
  41. account your_account ' new instance of type account
  42.  
  43. your_account.account_num = 2357666
  44. your_account.balance = 1000.00
  45. your_account.statement_of_account()
  46. your_account.pay_out(300.00)
  47. your_account.pay_in(100.00)
  48. your_account.statement_of_account()
  49.  
  50. printl cr & "Hit Enter ... " : waitkey
  51.  


.
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 09, 2016, 01:01:10 AM
And now I have learned how to hide data information using the 'private' or 'protected' keyword. This is really cool.

Code: OxygenBasic
  1. $filename "Banking.exe"
  2.  
  3. 'include "$/inc/RTL32.inc"
  4. 'include "$/inc/RTL64.inc"
  5.  
  6. % TryAttachConsole
  7. include "$/inc/console.inc"
  8.  
  9. SetConsoleTitle "Bank Transactions"
  10.  
  11. class account
  12.  
  13.   'data encapsulation - information hiding
  14.  private 'or protected
  15.  
  16.   ' Attributes
  17.  int account_num
  18.   double balance
  19.  
  20.   public
  21.  
  22.   ' methods for secure access
  23.  method get_account_num() as int
  24.     return account_num
  25.   end method
  26.  
  27.   method set_account_num(int number)
  28.     account_num = number
  29.   end method
  30.  
  31.   ' methods for secure access
  32.  method get_balance() as double
  33.     return balance
  34.   end method
  35.  
  36.   method set_balance(double amount)
  37.     balance = amount
  38.   end method  
  39.  
  40.   '
  41.  method pay_out(double amount)
  42.     balance -= amount
  43.     printl "Payed out: " str(amount) & " Euro"
  44.   end method
  45.  
  46.   method pay_in(double amount)
  47.     balance += amount
  48.     printl "Payed in: " str(amount) & " Euro"
  49.   end method
  50.  
  51.   method statement_of_account()
  52.     printl "Account Number: " & account_num & " Balance: " & str(balance) & " Euro"
  53.   end method
  54.  
  55. end class
  56.  
  57. account my_account ' new instance of type account
  58.  
  59. 'my_account.account_num = 1234567
  60. 'my_account.balance = 100.00
  61. 'printl "Account Number: " & my_account.account_num & " Balance: " & my_account.balance
  62. my_account.set_account_num(1234567) ' write access via method
  63. my_account.set_balance(100.00)
  64. printl "Account Number: " & my_account.get_account_num() ' read access
  65. print " Balance: " & my_account.get_balance() & " Euro"
  66.  
  67. my_account.pay_out(600.00)
  68. my_account.statement_of_account()
  69. printl()
  70.  
  71. account your_account ' new instance of type account
  72.  
  73. 'your_account.account_num = 2357666
  74. 'your_account.balance = 1000.00
  75. your_account.set_account_num(2357666) ' write access via method
  76. your_account.set_balance(1000.00)
  77.  
  78. your_account.statement_of_account()
  79. your_account.pay_out(300.00)
  80. your_account.pay_in(100.00)
  81. your_account.statement_of_account()
  82.  
  83. printl cr & "Hit Enter ... " : waitkey
  84.  
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 09, 2016, 02:29:39 AM

Hi Roland,

Yes, the political scene is very strange this summer.

Here is my take on your first example: The methods are placed inside the class block, so there is no need for the methods block. O2 will generate it automaticallly.

Also, null strings are treated as boolean false:

Code: OxygenBasic
  1. class entity
  2.  
  3.   to_whom as string
  4.   what_prop as string
  5.  
  6.   method greet() as string
  7.   method = "Hello "
  8.   if what_prop then method += what_prop & " "
  9.   if to_whom then method += to_whom
  10.   end method
  11.  
  12.   method say_goodbye() as string
  13.   method = "Goodbye "
  14.   if what_prop then method += what_prop & " "
  15.   if to_whom then method += to_whom
  16.   end method
  17.  
  18. end class
  19.  
  20.  
  21. 'TEST
  22.  
  23. entity we
  24. printl we.greet()
  25. printl we.say_goodbye()
  26. we.to_whom = "World"
  27. printl we.greet()
  28. printl we.say_goodbye()
  29.  
  30. entity I
  31. I.to_whom = "Susanne"
  32. I.what_prop = "beautiful"
  33. printl I.greet()
  34.  
  35. I.to_whom = "Kate"
  36. I.what_prop = "cruel"
  37. printl I.say_goodbye()
  38.  
  39. printl cr & "Hit Enter ... " : waitkey
  40. [/o2]
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 09, 2016, 07:22:04 AM
Thanks for discovering the error in examples\oop\Superstring. The bug caused an incorrect array index offset with indirect (pointered) members. It will be fixed on the next update.




method for cancelling account:

Code: OxygenBasic
  1. method cancel_account()
  2. if balance>0
  3.   pay_out balance
  4.   printl "Account closed"
  5.   balance=0
  6.   account_num=0
  7. elseif balance<0
  8.   printl "Please pay: " str(-balance) & " Euro " & "before cancelling account"
  9. else 'balance=0
  10.  printl "Account closed"
  11.   account_num=0
  12. end if
  13. end method
  14.  

Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 10, 2016, 12:50:31 AM
Hi Charles,

thank you for the revised code of class entity. I wondered about the usage of the 'methods' approach. Exploring the code of examples\OOP\ClassBasic.o2bas, ClassFormat2.o2bas, Interface1.o2bas I think I saw some occasions when to apply this.

Quote
Also, null strings are treated as boolean false:

This was news for me but it will make coding life easier. Using Oxygenbasic I can always find undiscovered features.

Thank you also for the cancel_account method which will also cover the situation of a positive or even balance. This method looks very easy (but only after I have seen it coded).

Roland
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 10, 2016, 03:25:37 AM
Hello,

in the meantime I learned that I can provide a class with initial values using the constructor method and then use the 'new' keyword for creating a new instance of the class. Until now everything makes sense to me.

Roland

Code: OxygenBasic
  1. $filename "Banking.exe"
  2.  
  3. 'include "$/inc/RTL32.inc"
  4. 'include "$/inc/RTL64.inc"
  5.  
  6. % TryAttachConsole
  7. include "$/inc/console.inc"
  8.  
  9. SetConsoleTitle "Bank Transactions"
  10.  
  11. class account
  12.  
  13.   'data encapsulation - information hiding
  14.  private 'or protected
  15.  
  16.   ' Attributes
  17.  int account_num
  18.   double balance
  19.  
  20.   public
  21.  
  22.   ' initialize
  23.  method constructor(int number)
  24.     account_num = number
  25.     balance = 0.0
  26.   end method
  27.  
  28.   ' methods for secure access
  29.  method get_account_num() as int
  30.     return account_num
  31.   end method
  32.  
  33.   ' set_account_num(number) removed
  34.  
  35.   ' methods for secure access
  36.  method get_balance() as double
  37.     return balance
  38.   end method
  39.  
  40.   ' set_balance(amount) removed
  41.  
  42.   '
  43.  method pay_out(double amount)
  44.     balance -= amount
  45.     printl "Payed out: " str(amount) & " Euro"
  46.   end method
  47.  
  48.   method pay_in(double amount)
  49.     balance += amount
  50.     printl "Payed in: " str(amount) & " Euro"
  51.   end method
  52.  
  53.   method statement_of_account()
  54.     printl "Account Number: " & account_num & " Balance: " & str(balance) & " Euro"
  55.   end method
  56.  
  57. end class
  58.  
  59. new account my_account(1234567) ' new instance of type account
  60.  
  61. printl "Account Number: " & my_account.get_account_num() ' read access
  62. print " Balance: " & my_account.get_balance() & " Euro"
  63.  
  64. my_account.pay_in(100.00)
  65. my_account.pay_out(600.00)
  66. my_account.statement_of_account()
  67. printl()
  68.  
  69. new account your_account(2357666) ' new instance of type account
  70.  
  71. your_account.statement_of_account()
  72.  
  73. your_account.pay_in(1000.00)
  74. your_account.pay_out(300.00)
  75. your_account.pay_in(100.00)
  76. your_account.statement_of_account()
  77.  
  78. printl cr & "Hit Enter ... " : waitkey
  79.  

Output:
Account Number: 1234567 Balance: 0 Euro
Payed in: 100 Euro
Payed out: 600 Euro
Account Number: 1234567 Balance: -500 Euro

Account Number: 2357666 Balance: 0 Euro
Payed in: 1000 Euro
Payed out: 300 Euro
Payed in: 100 Euro
Account Number: 2357666 Balance: 800 Euro

Hit Enter ...
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 11, 2016, 03:26:08 AM

Hi Roland,

new allocates space for the object, which should eventually be be released with del.

del  calls destructor() before releasing the object space, so you will also need:

method destructor()
...
end method
Title: Re: Starting Oop with OxygenBasic - please help
Post by: Arnold on August 11, 2016, 05:08:45 AM
Hi Charles,

with this example I get into difficulties now and although I am sure that the solution can be found in the Oxygenbasic examples I seem not to see the wood for the trees.

I would like to create an account our_account which is identical with your_account (quasi a shared account). Then I want to check if my_account or your_account is identical with our_account. Finally I want to transfer some money from my_account to your_account (which is our_account). But nothing works and the program crashes at the end.

I assume I must reference our_account to your_account somehow. But until now I failed to do this. Can you please help out and show me the right path?

Roland

Code: [Select]
deleted, faulty references

Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 11, 2016, 07:36:11 AM
My solution is to couple our_account and your_account by reference.

Code: OxygenBasic
  1. account our_account at @your_account
  2. 'equiv: account *our_account : @our_account = @your_account
  3.  

I have also incorporated three additional methods, the last replacing your 'sub transfer'

Code: OxygenBasic
  1.   method destructor()
  2.   end method
  3.  
  4.   method same_account_num(account *a,*b) as int
  5.     sys aa=a.get_account_num
  6.     sys bb=b.get_account_num
  7.     if aa=bb then return -1
  8.   end method
  9.  
  10.   method transfer(double amount, account *account_A, *account_Z)
  11.     account_A.statement_of_account()
  12.     account_Z.statement_of_account()
  13.     account_A.pay_out(amount)
  14.     account_Z.pay_in(amount)
  15.     printl "From Account Number: " & account_A.get_account_num()
  16.     print " transferred " & amount & " Euro"
  17.     print " to Account Number: " & account_Z.get_account_num() & cr
  18.     account_A.statement_of_account()
  19.     account_Z.statement_of_account()
  20.   end method
  21.  
  22.  

So in full:
Code: [Select]
$filename "Banking.exe"

'include "$/inc/RTL32.inc"
'include "$/inc/RTL64.inc"

% TryAttachConsole
include "$/inc/console.inc"

SetConsoleTitle "Bank Transactions"

class account

  static int count    'class variable

  'data encapsulation - information hiding
  private 'or protected 
  ' Attributes
  int account_num     'instance variables
  double balance

  public

  ' initialize
  method constructor(int number)
    count += 1
    account_num = number
    balance = 0.00
  end method
 
  method destructor()
  end method

  ' method for secure access
  method get_account_num() as int
    return account_num
  end method

  ' method for secure access
  method get_balance() as double
    return balance
  end method

  '
  method pay_in(double amount)
    balance += amount
    printl "Payed in: " str(amount) & " Euro"
  end method

  method pay_out(double amount)
    balance -= amount
    printl "Payed out: " str(amount) & " Euro"
  end method
   
  method statement_of_account()
    printl "Account Number: " & account_num & " Balance: " & str(balance) & " Euro"
  end method
 
  method same_account_num(account *a,*b) as int
    sys aa=a.get_account_num
    sys bb=b.get_account_num
    if aa=bb then return -1
  end method

  method transfer(double amount, account *account_A, *account_Z)
    account_A.statement_of_account()
    account_Z.statement_of_account()
    account_A.pay_out(amount)
    account_Z.pay_in(amount)
    printl "From Account Number: " & account_A.get_account_num()
    print " transferred " & amount & " Euro"
    print " to Account Number: " & account_Z.get_account_num() & cr
    account_A.statement_of_account()
    account_Z.statement_of_account()
  end method

end class


' Access class variable via class name
printl "Number of Accounts: " & account.count
new account my_account(1234567)   ' new instance of type account
printl "Account Number: " & my_account.get_account_num() ' read access
print " Balance: " & my_account.get_balance() & " Euro"
printl "Number of Accounts: " & account.count
new account your_account(2357666) ' new instance of type account
your_account.statement_of_account()
printl "Number of Accounts: " & account.count

' Assigning (coupling by reference)

account our_account at @your_account
'equiv: account *our_account : @our_account = @your_account
printl "Account Number: " & our_account.get_account_num() ' read access
print " Balance: " & our_account.get_balance() & " Euro"
our_account.statement_of_account()
printl "Number of Accounts: " & account.count

printl

'/*
if account.same_account_num(my_account,your_account) then
  printl "My account and your account are identical."
else
  printl "My account and your account are different."
end if

if account.same_account_num(our_account,your_account) then
  printl "Our account and your account are identical."
else
  printl "Our account and your account are different."
end if
'*/


my_account.pay_in(2000.00)
my_account.statement_of_account()
printl()

your_account.pay_in(100.00)
your_account.statement_of_account()
printl

our_account.pay_in(200.00)
our_account.statement_of_account()  'should be 300
printl

'do it

account.transfer(30.00, my_account, your_account)

printl cr & "Hit Enter ... " : waitkey

del my_account
del your_account 'alias our_account
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 11, 2016, 10:14:19 AM
Hi Charles,

thank you a lot for this solution which was really very helpful for me. I always do the same mistake with pointers. Although I found: account our_account at @your_account, I did not treat the references correctly afterwards. I corrected my code and I now get the correct results.

Comparing with your code I assume it is not a good programming style to mix methods and procedures/functions?

Is applying the destructor() method mandatory when using a constructor() method?

Roland

Code: [Select]
$filename "Banking.exe"

'include "$/inc/RTL32.inc"
'include "$/inc/RTL64.inc"

% TryAttachConsole
include "$/inc/console.inc"

SetConsoleTitle "Bank Transactions"

class account

  static int count    'class variable

  'data encapsulation - information hiding
  private 'or protected 
  ' Attributes
  int account_num     'instance variables
  double balance

  public

  ' initialize
  method constructor(int number)
    count += 1
    account_num = number
    balance = 0.00
  end method

  method destructor()
  end method
 
  ' method for secure access
  method get_account_num() as int
    return account_num
  end method

  ' method for secure access
  method get_balance() as double
    return balance
  end method

  '
  method pay_in(double amount)
    balance += amount
    printl "Payed in: " str(amount) & " Euro"
  end method

  method pay_out(double amount)
    balance -= amount
    printl "Payed out: " str(amount) & " Euro"
  end method
   
  method statement_of_account()
    printl "Account Number: " & account_num & " Balance: " & str(balance) & " Euro"
  end method
 
end class


' Access class variable via class name
printl "Number of Accounts: " & account.count
new account my_account(1234567)   ' new instance of type account
printl "Account Number: " & my_account.get_account_num() ' read access
print " Balance: " & my_account.get_balance() & " Euro"
printl "Number of Accounts: " & account.count
new account your_account(2357666) ' new instance of type account
your_account.statement_of_account()
printl "Number of Accounts: " & account.count

' Assigning (coupling by reference)
account our_account at @your_account
'equiv: account *our_account : @our_account = @your_account
printl "Account Number: " & our_account.get_account_num() ' read access
print " Balance: " & our_account.get_balance() & " Euro"
our_account.statement_of_account()
printl "Number of Accounts: " & account.count

printl

if @my_account = @your_account then
  printl "My account and your account are identical."
else
  printl "My account and your account are different."
end if

if @our_account = @your_account then
  printl "Our account and your account are identical."
else
  printl "Our account and your account are different."
end if

my_account.pay_in(2000.00)
my_account.statement_of_account()
printl()

your_account.pay_in(100.00)
your_account.statement_of_account()
printl

our_account.pay_in(200.00)
our_account.statement_of_account()  'should be 300
printl

sub transfer(double amount, account *a, *b)
  account account_A at @a
  account account_Z at @b
  account_A.statement_of_account()
  account_Z.statement_of_account()
  account_A.pay_out(amount)
  account_Z.pay_in(amount)
  printl "From Account Number: " & account_A.get_account_num()
  print " transferred " & amount & " Euro"
  print " to Account Number: " & account_Z.get_account_num() & cr
  account_A.statement_of_account()
  account_Z.statement_of_account()
end sub

'transfer money
transfer(30.00, my_account, your_account)

del my_account
del your_account 'alias our_account

printl cr & "Hit Enter ... " : waitkey
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 12, 2016, 01:57:12 AM
Hi Roland,

Comparing with your code I assume it is not a good programming style to mix methods and procedures/functions?

Keeping all your banking procedures together within the account class will make code maintenance easier, especially when you want to combine accounts with other classes. Encapsulation becomes increasingly important, as programs become more complex.

Is applying the destructor() method mandatory when using a constructor() method?

Yes, the dynamic space occupied by the object, should be freed at the end of the object's lifetime.
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 13, 2016, 04:36:13 AM
Hi Charles,

with this example I start using inheritance. When I read about OOP in the past at this stage I lost the way and everything looked like magic then.

I created a class savings_account which inherits from account and which can yield interest. In the Java example this is done using the keyword 'extends'.  For OxygenBasic I used 'has'. There is a problem though:

Java extends the constructor of savings_account using: super(number)' uses constructor of superclass account. I tried to replace this with the three variables:

  ' constructor of class savings_account
  method constructor(int number, double interest)
// Java:    super(number)' uses constructor of superclass account

    count += 1            'not equivalent
    account_num = number
'    balance = 0.00
 
    rate_percent = interest
  end method

but this seems not to be correct. Is there another way to get count, account_num and balance? (rate_percent is a new attribute).

After all I am not sure if constructor/new and destructor/del is necessary at all for this kind of classes? Maybe I should only use a method initialize?

Roland

Code: [Select]
  $filename "Banking.exe"

'include "$/inc/RTL32.inc"
'include "$/inc/RTL64.inc"

% TryAttachConsole
include "$/inc/console.inc"

SetConsoleTitle "Bank Transactions"

class account

  static int count    'class variable

  'data encapsulation - information hiding
  protected ' or private
  ' Attributes
  int account_num     'instance variables
  double balance

  public

  ' initialize
  method constructor(int number)
    count += 1
    account_num = number
    balance = 0.00
  end method
 
  method destructor()
  end method

  ' method for secure access
  method get_account_num() as int
    return account_num
  end method

  ' method for secure access
  method get_balance() as double
    return balance
  end method

  '
  method pay_in(double amount)
    balance += amount
    printl "Payed in: " str(amount) & " Euro"
  end method

  method pay_out(double amount)
    balance -= amount
    printl "Payed out: " str(amount) & " Euro"
  end method
   
  method statement_of_account()
    printl "Account Number: " & account_num & " Balance: " & str(balance,2) & " Euro"
  end method
 
  method same_account_num(account *a,*b) as int
    sys aa=a.get_account_num
    sys bb=b.get_account_num
    if aa=bb then return -1
  end method

  method transfer(double amount, account *account_A, *account_Z)
    account_A.statement_of_account()
    account_Z.statement_of_account()
    account_A.pay_out(amount)
    account_Z.pay_in(amount)
    printl "From Account Number: " & account_A.get_account_num()
    print " transferred " & amount & " Euro"
    print " to Account Number: " & account_Z.get_account_num() & cr
    account_A.statement_of_account()
    account_Z.statement_of_account()
  end method

end class

' --> Inheritance
class savings_account

  has account
 
  private
  double rate_percent' ' additional attribute

  public
 
  ' constructor of class savings_account
  method constructor(int number, double interest)
// Java:    super(number)' uses constructor of superclass account

    count += 1            'not equivalent
    account_num = number
'    balance = 0.00
 
    rate_percent = interest
  end method

  method destructor()
  end method

  ' new methods for accessing attribute rate_percent
  method get_rate_percent() as double
    return rate_percent'
  end method

  method set_rate_percent(double interest)
    rate_percent = interest'
  end method
 
  ' new method
  method pay_interest()
    double interest_payable = (rate_percent * balance)/100)
    printl "Interest payable: " & str(interest_payable,2)
    balance += interest_payable ' uses inherited attributes
  end method

end class



' Access class variable via class name
printl "Number of Accounts: " & account.count
new account my_account(1234567)   ' new instance of type account
printl "Account Number: " & my_account.get_account_num() ' read access
print " Balance: " & my_account.get_balance() & " Euro"
printl "Number of Accounts: " & account.count
new account your_account(2357666) ' new instance of type account
your_account.statement_of_account()
printl "Number of Accounts: " & account.count

' Assigning (coupling by reference)
account our_account at @your_account
'equiv: account *our_account : @our_account = @your_account
printl "Account Number: " & our_account.get_account_num() ' read access
print " Balance: " & our_account.get_balance() & " Euro"
our_account.statement_of_account()
printl "Number of Accounts: " & account.count
printl


if account.same_account_num(my_account, your_account) then
  printl "My account and your account are identical."
else
  printl "My account and your account are different."
end if

if account.same_account_num(our_account, your_account) then
  printl "Our account and your account are identical."
else
  printl "Our account and your account are different."
end if


my_account.pay_in(2000.00)
my_account.statement_of_account()
printl

your_account.pay_in(100.00)
your_account.statement_of_account()
printl

our_account.pay_in(200.00)
our_account.statement_of_account()
printl

'transfer some money
account.transfer(30.00, my_account, your_account)
printl

' Inheritance

new savings_account my_savings_account(4444990, 5.2)

'each instance of class savings_account has 3 attributes
printl "Account Number: " & my_savings_account.get_account_num() 'inherited attribute
print " Balance: " & my_savings_account.get_balance() &" Euro"'  'inherited attribute
printl "Rate Percent: " & str(my_savings_account.get_rate_percent(),2)' ' new declared attribute
printl "Number of Accounts: " & account.count

'method pay_in(amount), pay_out(amount) and statement_of_account() can be used
my_savings_account.pay_in(250.00)  'inherited methods
my_savings_account.statement_of_account()'
my_savings_account.pay_out(10.00)'
my_savings_account.statement_of_account()

'instances of class savings_account can use the method pay_interest()
my_savings_account.pay_interest()' ' new method
my_savings_account.statement_of_account()'

printl cr & "Hit Enter ... " : waitkey

del my_account
del your_account 'alias our_account
del my_savings_account

Output:
....
....
Account Number: 4444990 Balance: 0 Euro
Rate Percent: 5.2
Number of Accounts: 2       --> should be 3
Payed in: 250 Euro
Account Number: 4444990 Balance: 250 Euro
Payed out: 10 Euro
Account Number: 4444990 Balance: 240 Euro
Interest payable: 12.48
Account Number: 4444990 Balance: 252.48 Euro

Hit Enter ...
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 14, 2016, 02:48:24 AM
Hi Roland,

The static members and the constructor/deconstructor methods of the base class are currently inaccessible. But I have a new release of o2 which supports calls to base constructors and destructors.

It will also do the same for multiple inheritance:to call all the member constructors.

I'm still testing, but I hope to release it within the next 2 weeks or so.
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 14, 2016, 11:38:11 PM
Hi Charles,

it began to dawn on me that I can see the constructor method as a means to construct a 'new' instance of a class with some initialized attributes, similar like a procedure with arguments. This was not obvious to me in the past and so I failed afterwards. (Sorry for my ignorance). If it will be possible in the future to derive constructor methods from base classes this will be fine. The example I refer to was coded in several languages which all seem to be able to create and use constructors.

But if I have understood this basic principle correctly then at the same time it should be possible to get the results without constructors at all - like using procedures without arguments. So I modified the code and this is what came out. If I did everything properly then I reached a real milestone in OOP.

Roland

Code: [Select]
  $filename "Banking.exe"

'include "$/inc/RTL32.inc"
'include "$/inc/RTL64.inc"

% TryAttachConsole
include "$/inc/console.inc"

SetConsoleTitle "Bank Transactions"

class account

  static int count    'class variable

  'data encapsulation - information hiding
  protected ' or private
  ' Attributes
  int account_num     'instance variables
  double balance

  public

  method init()
    count += 1
    balance = 0.00 
  end method

  ' methods for secure access
  method set_account_num(int number)
    account_num = number
  end method

  method get_account_num() as int
    return account_num
  end method

  method get_balance() as double
    return balance
  end method

  method pay_in(double amount)
    balance += amount
    printl "Payed in: " str(amount) & " Euro"
  end method

  method pay_out(double amount)
    balance -= amount
    printl "Payed out: " str(amount) & " Euro"
  end method
   
  method statement_of_account()
    printl "Account Number: " & account_num & " Balance: " & str(balance,2) & " Euro"
  end method
 
  method same_account_num(account *a,*b) as int
    sys aa=a.get_account_num
    sys bb=b.get_account_num
    if aa=bb then return -1
  end method

  method transfer(double amount, account *account_A, *account_Z)
    account_A.statement_of_account()
    account_Z.statement_of_account()
    account_A.pay_out(amount)
    account_Z.pay_in(amount)
    printl "From Account Number: " & account_A.get_account_num()
    print " transferred " & amount & " Euro"
    print " to Account Number: " & account_Z.get_account_num() & cr
    account_A.statement_of_account()
    account_Z.statement_of_account()
  end method

end class

' --> Inheritance
class savings_account

  has account
 
  private
  double rate_percent' ' additional attribute

  public
 
  ' new methods for accessing attribute rate_percent
  method get_rate_percent() as double
    return rate_percent'
  end method

  method set_rate_percent(double interest)
    rate_percent = interest'
  end method
 
  ' new method
  method pay_interest()
    double interest_payable = (rate_percent * balance)/100)
    printl "Interest payable: " & str(interest_payable,2)
    balance += interest_payable ' uses inherited attributes
  end method

end class



' Access class variable via class name
printl "Number of Accounts: " & account.count
account my_account   ' new instance of type account
my_account.init()
my_account.set_account_num(1234567)
printl "Account Number: " & my_account.get_account_num() ' read access
print " Balance: " & my_account.get_balance() & " Euro"
printl "Number of Accounts: " & account.count
account your_account ' new instance of type account
your_account.init()
your_account.set_account_num(2357666)
your_account.statement_of_account()
printl "Number of Accounts: " & account.count

' Assigning (coupling by reference)
account our_account at @your_account
'equiv: account *our_account : @our_account = @your_account
printl "Account Number: " & our_account.get_account_num() ' read access
print " Balance: " & our_account.get_balance() & " Euro"
our_account.statement_of_account()
printl "Number of Accounts: " & account.count
printl


if account.same_account_num(my_account, your_account) then
  printl "My account and your account are identical."
else
  printl "My account and your account are different."
end if

if account.same_account_num(our_account, your_account) then
  printl "Our account and your account are identical."
else
  printl "Our account and your account are different."
end if


my_account.pay_in(2000.00)
my_account.statement_of_account()
printl

your_account.pay_in(100.00)
your_account.statement_of_account()
printl

our_account.pay_in(200.00)
our_account.statement_of_account()
printl

'transfer some money
account.transfer(30.00, my_account, your_account)
printl

' Inheritance

savings_account my_savings_account'(4444990, 5.2)
my_savings_account.init()
my_savings_account.set_account_num(4444990)
my_savings_account.set_rate_percent(5.2)

'each instance of class savings_account has 3 attributes
printl "Account Number: " & my_savings_account.get_account_num() 'inherited attribute
print " Balance: " & my_savings_account.get_balance() &" Euro"'  'inherited attribute
printl "Rate Percent: " & str(my_savings_account.get_rate_percent(),2)' ' new declared attribute
printl "Number of Accounts: " & account.count

'method pay_in(amount), pay_out(amount) and statement_of_account() can be used
my_savings_account.pay_in(250.00)  'inherited methods
my_savings_account.statement_of_account()'
my_savings_account.pay_out(10.00)'
my_savings_account.statement_of_account()

'instances of class savings_account can use the method pay_interest()
my_savings_account.pay_interest()' ' new method
my_savings_account.statement_of_account()'

printl cr & "Hit Enter ... " : waitkey

Output:
Number of Accounts: 0
Account Number: 1234567 Balance: 0 Euro
Number of Accounts: 1
Account Number: 2357666 Balance: 0 Euro
Number of Accounts: 2
Account Number: 2357666 Balance: 0 Euro
Account Number: 2357666 Balance: 0 Euro
Number of Accounts: 2

My account and your account are different.
Our account and your account are identical.
Payed in: 2000 Euro
Account Number: 1234567 Balance: 2000 Euro

Payed in: 100 Euro
Account Number: 2357666 Balance: 100 Euro

Payed in: 200 Euro
Account Number: 2357666 Balance: 300 Euro

Account Number: 1234567 Balance: 2000 Euro
Account Number: 2357666 Balance: 300 Euro
Payed out: 30 Euro
Payed in: 30 Euro
From Account Number: 1234567 transferred 30 Euro to Account Number: 2357666

Account Number: 1234567 Balance: 1970 Euro
Account Number: 2357666 Balance: 330 Euro

Account Number: 4444990 Balance: 0 Euro
Rate Percent: 5.2
Number of Accounts: 3
Payed in: 250 Euro
Account Number: 4444990 Balance: 250 Euro
Payed out: 10 Euro
Account Number: 4444990 Balance: 240 Euro
Interest payable: 12.48
Account Number: 4444990 Balance: 252.48 Euro
Title: Re: Starting Oop with OxygenBasic
Post by: Aurel on August 15, 2016, 12:06:39 AM
Hi..
I am back..  :D
Yes OOP in Oxgen is one of the best and simpliest OOP way
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 15, 2016, 01:06:28 AM
Hi Aurel,

Yes I try to keep the OOP as simple as possible. Constructor and Destructor methods are only necessary when using new and del.

Hi Roland,

Referring back to accessing the base constructor.

If you name the base class member, you will be able to access its constructor and destructor methods:

class cc
has bb bbase
...
bbase.constructor()

Code: [Select]
'ACCESSING THE BASE CLASS BY SPECIFIED NAME
class bb
  private static sys counter

  method constructor()
  counter++
  end method

  method destructor()
  end method

  method CounterVal() as int
  return counter
  end method
end class

class cc
  has bb bbase 'give a name to the base class bb

  method constructor()
  bbase.constructor()
  end method

  method destructor()
  bbase.destructor()
  end method
end class

new cc c
print c.bbase.counterVal()
del c
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 16, 2016, 12:19:34 AM
Hi Charles,

by using OxygenBasic I learned so many things which I as an autodidact did not understand before. I incorporated your counter method and used constructor again.

This last example deals with overriding methods. It will complete my exploring the basic principles of OOP and I will then try some own simple apps. For the notation I changed the naming a little bit and used camel case most of the time

There are the classes account which is initialized with number and the class savingsAccount which has account and is initialized with number and interest rate.
I created a class giroAccount which has account and is initialized with number and credit limit. It uses a method pay_out which overrides the method of account. I used this method:

  ' --> reimplementation
  method pay_out(double amount)
    if amount <= (balance + limit) then
'      account.pay_out(amount) ' does not work for statement_of_account
      balance -= amount
      printl "Payed out: " str(amount) & " Euro"
    else
      printl "Exceeded Limit!"
    end if
  end method


Would it be possible to use the method pay_out() of class account in some way? When I try account.pay_out then myGiroAccount.statement_of_account() does not show the correct result. Therefore I used the equivalent statements.

Hopefully it is ok that I append the full code. (many statements were done before). It contains everything I learned about OOP so far and how it can be done with OxygenBasic. So it could be interesting for other people too who would like to start with OOP.

Roland

Code: [Select]
' Account7.o2bas

  $filename "Banking.exe"

'include "$/inc/RTL32.inc"
'include "$/inc/RTL64.inc"

% TryAttachConsole
include "$/inc/console.inc"

SetConsoleTitle "Bank Transactions"

'accessing the base class by specified name
class counter
  private static sys counterVal

  method constructor()
  counterVal++
  end method

  method destructor()
  end method

  method count() as int
  return counterVal
  end method
end class

class account

  has counter num 'give a name to the base class counter

  'data encapsulation - information hiding
  protected ' or private
  ' Attributes
  int accountNumber     'instance variables
  double balance

  public

  ' initialize
  method constructor(int number)
    num.constructor
   
    accountNumber = number
    balance = 0.00
  end method
 
  method destructor()
    num.destructor
  end method

  ' methods for secure access
  method getAccountNumber() as int
    return accountNumber
  end method

  method getBalance() as double
    return balance
  end method

  method pay_in(double amount)
    balance += amount
    printl "Payed in: " str(amount) & " Euro"
  end method

  method pay_out(double amount)
    balance -= amount
    printl "Payed out: " str(amount) & " Euro"
  end method
   
  method statement_of_account()
    printl "Account Number: " & accountNumber & " Balance: " & str(balance,2) & " Euro"
  end method
 
  method sameAccountNumber(account *a,*b) as int
    sys aa=a.getAccountNumber
    sys bb=b.getAccountNumber
    if aa=bb then return -1
  end method

  method transfer(double amount, account *account_A, *account_Z)
    account_A.statement_of_account()
    account_Z.statement_of_account()
    account_A.pay_out(amount)
    account_Z.pay_in(amount)
    printl "From Account Number: " & account_A.getAccountNumber()
    print " transferred " & amount & " Euro"
    print " to Account Number: " & account_Z.getAccountNumber() & cr
    account_A.statement_of_account()
    account_Z.statement_of_account()
  end method

end class

' --> Inheritance
class savingsAccount

  has account
 
  private
  double ratePercent ' additional attribute

  public
 
  ' constructor of class savingsAccount
  method constructor(int number, double interest)
    num.constructor()

    accountNumber = number
    balance = 0.00
 
    ratePercent = interest
  end method

  method destructor()
    num.destructor()
  end method

  ' new methods for accessing attribute ratePercent
  method getRatePercent() as double
    return ratePercent'
  end method

  method setRatePercent(double interest)
    ratePercent = interest'
  end method
 
  ' new method
  method pay_interest()
    double interest_payable = (ratePercent * balance)/100)
    printl "Interest payable: " & str(interest_payable,2)
    balance += interest_payable ' uses inherited attributes
  end method

end class


' --> overriding, reimplementation
class giroAccount

  has account

  private 
  double limit
 
  public
 
  method constructor(int number, double bankLine)
    num.constructor()

    accountNumber = number
    limit = abs(bankLine)
  end method

  method destructor()
    num.destructor()
  end method

  method getLimit() as double
    return limit
  end method
 
  ' method for access, check if arg is positiv
  method setLimit(double limit)
    limit = abs(limit)
  end method

  ' --> reimplementation
  method pay_out(double amount)
    if amount <= (balance + limit) then
'      account.pay_out(amount) ' does not work for statement_of_account
      balance -= amount
      printl "Payed out: " str(amount) & " Euro"
    else
      printl "Exceeded Limit!"
    end if
  end method

end class


' Access class variable via class name
printl "Number of Accounts: " & account.num.count
new account myAccount(1234567)   ' new instance of type account
printl "Account Number: " & myAccount.getAccountNumber() ' read access
print " Balance: " & myAccount.getBalance() & " Euro"
printl "Number of Accounts: " & account.num.count
new account yourAccount(2357666) ' new instance of type account
yourAccount.statement_of_account()
printl "Number of Accounts: " & account.num.count

' Assigning (coupling by reference)
account ourAccount at @yourAccount
'equiv: account *ourAccount : @ourAccount = @yourAccount
ourAccount.statement_of_account()
printl "Number of Accounts: " & account.num.count
printl


if account.sameAccountNumber(myAccount, yourAccount) then
  printl "My account and your account are identical."
else
  printl "My account and your account are different."
end if

if account.sameAccountNumber(ourAccount, yourAccount) then
  printl "Our account and your account are identical."
else
  printl "Our account and your account are different."
end if
printl

myAccount.pay_in(2000.00)
myAccount.statement_of_account()
printl

yourAccount.pay_in(100.00)
yourAccount.statement_of_account()
printl

ourAccount.pay_in(200.00)
ourAccount.statement_of_account()
printl

'transfer some money
account.transfer(30.00, myAccount, yourAccount)
printl

' Inheritance

new savingsAccount mySavingsAccount(4444990, 5.2)

'each instance of class savingsAccount has 3 attributes
printl "Account Number: " & mySavingsAccount.getAccountNumber() 'inherited attribute
print " Balance: " & mySavingsAccount.getBalance() &" Euro"'  'inherited attribute
printl "Rate Percent: " & str(mySavingsAccount.getRatePercent(),2)' ' new declared attribute
printl "Number of Accounts: " & account.num.count

'method pay_in(amount), pay_out(amount) and statement_of_account() can be used
mySavingsAccount.pay_in(250.00)  'inherited methods
mySavingsAccount.statement_of_account()'
mySavingsAccount.pay_out(10.00)'
mySavingsAccount.statement_of_account()

'instances of class savingsAccount can use the method pay_interest()
mySavingsAccount.pay_interest()' ' new method
mySavingsAccount.statement_of_account()'
printl

' Reimplementation
myAccount.pay_out(1700.00) ' method pay_out(amout) of class account
myAccount.statement_of_account()
printl
printl "Trying to draw 5000 Euro."
myAccount.pay_out(5000.00) ' method pay_out(amout) of class account
myAccount.statement_of_account()
printl

new giroAccount myGiroAccount(1733065,100)
myGiroAccount.statement_of_account()
printl "Bank Line = " & myGiroAccount.getLimit()
printl "Number of Accounts: " & account.num.count
myGiroAccount.pay_in(400.00)
myGiroAccount.statement_of_account()
printl "Trying to draw 450 Euro."
myGiroAccount.pay_out(450.00) ' method pay_out(amout) of class giroAccount
myGiroAccount.statement_of_account()
printl "Trying to draw 350 Euro."
myGiroAccount.pay_out(350.00) ' method pay_out(amout) of class giroAccount
myGiroAccount.statement_of_account()

printl cr & "Hit Enter ... " : waitkey

del myAccount
del yourAccount 'alias ourAccount
del mySavingsAccount
del myGiroAccount

Output:
...
...
Payed out: 1700 Euro
Account Number: 1234567 Balance: 270 Euro

Trying to draw 5000 Euro.
Payed out: 5000 Euro
Account Number: 1234567 Balance: -4730 Euro

Account Number: 1733065 Balance: 0 Euro
Bank Line = 100
Number of Accounts: 4
Payed in: 400 Euro
Account Number: 1733065 Balance: 400 Euro
Trying to draw 450 Euro.
Payed out: 450 Euro
Account Number: 1733065 Balance: -50 Euro
Trying to draw 350 Euro.
Exceeded Limit!
Account Number: 1733065 Balance: -50 Euro

Hit Enter ...
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 16, 2016, 12:41:59 AM
I would like to ask a last question about the constructor method: Would it be possible to overload the constructors in a class so that I could use:

new account myAccount(number)
new account yourAccount(number, amount)

I saw that Java can use a second constructor overloading the first, some other languages cannot do this.

But I consider this question a little bit academic as I learned that I can initialize an instance of a class by using simple methods. I am not sure if I will need constructors for my projects at all.

Roland
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 16, 2016, 03:26:45 AM

in haste:

Yes, you can have several constructors with different prototypes. o2 will select the best match when a constructor is called.

Another approach is to use optional params. if the optional param is not used then the function will see it as null.
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 16, 2016, 08:12:05 AM
Hi Roland,

To answer your question on accessing a method which has been overridden:

      this technique can be used safely with single line inheritance (as in java)

      account a at @this
      a.pay_out(amount)

      for single line inheritance, use the term of or from instead of has.
      In the next release of o2, the term extends will also be understood.

Code: [Select]
' --> overriding, reimplementation
class giroAccount

  from account 'single line inheritance

  private 
  double limit
 
  public
 
  method constructor(int number, double bankLine)
    num.constructor()

    accountNumber = number
    limit = abs(bankLine)
  end method

  method destructor()
    num.destructor()
  end method

  method getLimit() as double
    return limit
  end method
 
  ' method for access, check if arg is positiv
  method setLimit(double limit)
    limit = abs(limit)
  end method

  ' --> reimplementation
  method pay_out(double amount)
    if amount <= (balance + limit) then
'      account.pay_out(amount) ' does not work for statement_of_account
'      invoking the class directly will only work for static elements
'      but this technique can be used safely with single line inheritance (as in java)
      account a at @this
      a.pay_out(amount)

'      balance -= amount
'      printl "Payed out: " str(amount) & " Euro"
    else
      printl "Exceeded Limit!"
    end if
  end method

end class
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 19, 2016, 07:27:34 AM
Hi Charles,

using 'from account' in class giroAccount and the two replacements in method pay_out worked quite nice. One of my future projects will be to investigate the possible uses of pointers in OxygenBasic. I have not yet found the correct clue for applying them although I know there must be a common logic for using them. And to handle them in other programming languages is not a bit easier.

The help file of Oxygen states:
'of', 'has' and 'from' currently means 'inherits. They indicate derivation from a single parental class.
I did not notice a difference between 'has' or 'from' when building the class giroAccount, but there is a distinction?

I also tried out polymorphism and added some more statements invoking different types for myAccount. This worked also quite nice. Will it be sufficient if I use 'del myAccount' once at the end of the program?

Roland

Code: OxygenBasic
  1. ...
  2. ...
  3. ' --> Polymorphism - single interface to entities of different types
  4. printl cr & "Polymorphism" & cr
  5.  
  6. account myAccount     ' Test: object of type account
  7.  
  8. new account myAccount(4531088) ' myAccount points to object of type account
  9. myAccount.pay_in(300.00)
  10. myAccount.pay_out(500.00) ' method pay_out(amount) of class account is called
  11. myAccount.statement_of_account()
  12. printl
  13.  
  14. new giroAccount myAccount(5613990,100) ' myAccount now points to object of type giroAccount
  15. myAccount.pay_in(300.00)
  16. myAccount.statement_of_account()
  17. printl "Trying to draw 500 Euro"
  18. myAccount.pay_out(500.00) ' method pay_out(amount) of class giroAccount is called
  19. ' --> polymorphism & dynamic binding
  20. myAccount.statement_of_account()
  21. printl
  22.  
  23. new savingsAccount myAccount(1733065,1.25) ' myAccount now points to object of type Typ savingsAccount
  24. myAccount.pay_in(400.00)
  25. myAccount.statement_of_account()
  26. myAccount.pay_out(500.00) ' method pay_out(amount) of class savingsAccount is called
  27. myAccount.statement_of_account()
  28.  
  29. myAccount.pay_interest()
  30. myAccount.statement_of_account()
  31.  
  32.  
  33. printl cr & "Hit Enter ... " : waitkey
  34.  
  35. del myAccount
  36. del yourAccount 'alias ourAccount
  37. del mySavingsAccount
  38. del myGiroAccount
  39.  

Output:
...
...
Polymorphism

Payed in: 300 Euro
Payed out: 500 Euro
Account Number: 4531088 Balance: -200 Euro

Payed in: 300 Euro
Account Number: 5613990 Balance: 300 Euro
Trying to draw 500 Euro
Exceeded Limit!
Account Number: 5613990 Balance: 300 Euro

Payed in: 400 Euro
Account Number: 1733065 Balance: 400 Euro
Payed out: 500 Euro
Account Number: 1733065 Balance: -100 Euro
Interest payable: -1.25
Account Number: 1733065 Balance: -101.25 Euro

Hit Enter ...
Title: Re: Starting Oop with OxygenBasic
Post by: Charles Pegge on August 20, 2016, 01:34:33 AM
Hi Roland,

The default form of inheritance is 'has'. This term can be omitted. It supports inheritance from multiple classes and types.

Single-line inheritance, using 'of' and 'from' ('extends') uses a different arrangement of virtual table pointers and offsets. COM uses this mode of inheritance, and in Java this is the only form of inheritance supported. Not so good when you want to combine say, Banking and Graphics in one object.

The difference becomes apparent when classes are exported.



'del' is all you need to remove a 'new' object. Constructor and Destructor methods are mainly used for Building/Dismantling associated structures and linkages, as well as setting initial values.
Title: Re: Starting Oop with OxygenBasic
Post by: Arnold on August 20, 2016, 07:43:14 AM
Hi Charles,

thanks for the explanatory notes.

This was the basis for my experiments with accounts (I omitted overloading the constructor method):
Grundkonzepte objektorientierter Programmierung (http://www.uni-jena.de/unijenamedia/Bilder/faculties/minet/casio/DidaktikDerInformatik/studentischeArbeiten/OOPBericht.pdf)
(Erratum page 66: Overloading of methods in Python is not possible - seems not to be valid any more)
The corresponding course was (is still?) offered to the students of the University of Jena (https://www.uni-jena.de/unijenamedia/Bilder/faculties/minet/casio/DidaktikDerInformatik/studentischeArbeiten/FolienHimmerlich.pdf)

Unfortunately I found the project thesis only in the german language but it was very helpful for me as it discusses the basics of OOP in a compact way and how to apply them in several programming languages. Probably I will never be able to create any program with these languages but it was very interesting to compare with Oxygen.

Two more examples are provided which will be worthwhile to elaborate, in particular 'Geometric shapes' because I noticed that OxygenBasic already provides classes and methods to handle them. But first of all I must find out which results are expected.

Roland