Author Topic: Starting Oop with OxygenBasic  (Read 6488 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Guest
Starting Oop with OxygenBasic
« 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


.
« Last Edit: August 26, 2016, 03:05:42 AM by Arnold »

JRS

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #1 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

Arnold

  • Guest
Re: Starting Oop - SuperString.o2bas
« Reply #2 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

Arnold

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #3 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.  


.

Arnold

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #4 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.  

Charles Pegge

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #5 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]

Charles Pegge

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #6 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.  

« Last Edit: August 09, 2016, 08:09:37 AM by Charles Pegge »

Arnold

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #7 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

Arnold

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #8 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 ...

Charles Pegge

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #9 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

Arnold

  • Guest
Re: Starting Oop with OxygenBasic - please help
« Reply #10 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

« Last Edit: August 14, 2016, 11:32:09 PM by Arnold »

Charles Pegge

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #11 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
« Last Edit: August 11, 2016, 07:45:41 AM by Charles Pegge »

Arnold

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #12 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

Charles Pegge

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #13 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.

Arnold

  • Guest
Re: Starting Oop with OxygenBasic
« Reply #14 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 ...
« Last Edit: August 13, 2016, 04:21:28 PM by Arnold »