| 1 | """ |
|---|
| 2 | CheckInheritanceAndImplementation.cobra |
|---|
| 3 | |
|---|
| 4 | To check if a value inherits a particular class, use the `inherits` operator |
|---|
| 5 | which gives a boolean value (true or false): |
|---|
| 6 | |
|---|
| 7 | isACar = vehicle inherits Car |
|---|
| 8 | |
|---|
| 9 | To check if a value implements a particular interface, use the `implements` |
|---|
| 10 | operator: |
|---|
| 11 | |
|---|
| 12 | isComparable = x implements IComparable |
|---|
| 13 | |
|---|
| 14 | If you use these in an `if` statement with a variable, you can treat the |
|---|
| 15 | variable as the given class or interface with no explicit typecasting: |
|---|
| 16 | |
|---|
| 17 | if vehicle inherits Car |
|---|
| 18 | vehicle.drive |
|---|
| 19 | carCrusher.crush(vehicle) |
|---|
| 20 | else if vehicle inherits Plane |
|---|
| 21 | vehicle.fly |
|---|
| 22 | airplaneGraveyard.take(vehicle) |
|---|
| 23 | |
|---|
| 24 | Of course, it would be nice if Car and Plane were derived from a common Vehicle |
|---|
| 25 | class with an `operate` method, but sometimes you don't have control over the |
|---|
| 26 | class hierarchy you are working with. |
|---|
| 27 | """ |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | class BankAccount |
|---|
| 31 | |
|---|
| 32 | def deposit(x as Object) |
|---|
| 33 | if x inherits Money |
|---|
| 34 | _balance += x.amount |
|---|
| 35 | else if x inherits decimal |
|---|
| 36 | _balance += x |
|---|
| 37 | else if x inherits int |
|---|
| 38 | _balance += x |
|---|
| 39 | else |
|---|
| 40 | throw FallThroughException(x) |
|---|
| 41 | |
|---|
| 42 | # ^ In a way this is a bad example. Since we have control over the code, |
|---|
| 43 | # providing method overloads of `deposit` would make the BankAccount interface |
|---|
| 44 | # more clear and the program run faster. |
|---|
| 45 | |
|---|
| 46 | def deposit2(x) # dynamic typed arg |
|---|
| 47 | if x inherits Money |
|---|
| 48 | _balance += x.amount |
|---|
| 49 | else |
|---|
| 50 | _balance = _balance + x # woops, += isn't implemented for dynamic yet |
|---|
| 51 | |
|---|
| 52 | get balance from var as decimal |
|---|
| 53 | |
|---|
| 54 | |
|---|
| 55 | class Money |
|---|
| 56 | |
|---|
| 57 | cue init(amount as decimal) |
|---|
| 58 | base.init |
|---|
| 59 | _amount = amount |
|---|
| 60 | |
|---|
| 61 | get amount from var as decimal |
|---|
| 62 | |
|---|
| 63 | |
|---|
| 64 | class Program |
|---|
| 65 | |
|---|
| 66 | def main |
|---|
| 67 | ba = BankAccount() |
|---|
| 68 | ba.deposit(10) |
|---|
| 69 | ba.deposit(Money(10)) |
|---|
| 70 | assert ba.balance == 20 |
|---|