![]() |
![]() |
|
home—lectures—exams—hws—breeze (snow day)
Last lecture, we saw one way of (nearly) implementing objects, just using functions and local-variables, nested so that the function's closures enforced data-hiding.
Today we'll think a bit about (a) class-based O.O. languages (like java), and (b) instance-based O.O. languages (like javascript).
Two uses of inheritances:
(a) express type constraints/promises (the primary use);
(b) Re-use code (it is discouraged to use subclassing just fore this).
An example of the latter is
pre-1.5 Java's
C++ allowed multiple inheritnace, which sounds like a fine idea at first.
abstract class Vehicle { double speed; boolean hasPassedInspection; abstract void turn(); abstract void accelerate( double amt ); void inspect() { hasPassedInspection = true; } } class Car :: Vehicle { double[] tirePressure; void changeTire() { ... }; // Implementations of all the Vehicle methods: void turnLeft() { ... }; // ... } class Boat :: Vechicle { double keelDepth; boolean anchor; void aweigh() { anchor = true; } // Implementations of all the Vehicle methods: void turnLeft() { ... }; // ... } |
class Spymobile :: Car, Boat { // You might think, nothing else needed -- we've inherited all aspects of both! /* * However, when you call a Spymobile's `turn` method, * which of the above to methods should get called? Both, or just one? * If both, in which order? * Somehow, we need to specify/resolve all fields and methods that occur * the nearest common ancester. * So you might have two fields named `super` -- `Car::super` and `Boat::super`, * and the Spymobile's code has to be clear about which it's using. * People worked around that, but had bugs introduced in more subtle ways: */ } |
typedef (C):
the
One particularly useful scenario is having
C++ allows operator overloading — if you made a
However, operator-overloading is mostly discouraged in many project
guidelines.
The reason is that although convenient for a few numeric types (as above),
it also often leads to confusion.
Perhaps there is a type
(This sort of assumption/bug is always an issue, but operator-overloading makes
such glib bugs easier to introduce.)
Another problem with operator overloading is that people were tempted
to take it too far, overloading the operators
Useful for:
PHP uses pass-by-value, by default. Here's what that means: When calling a function: All values are written down and handed to the function; the function copies that value into its parameter/variable.
In particular, when you pass an array (or any object), a clone of that entire array is made, and passed. In fact, even when you assign one array to another, a copy is made:
1 <?php 2 3 $a = 5; 4 $b = $a; // a *copy* of 5 is made. 5 6 $x = array(1,2,3,4); 7 $y = $x; // a *copy* of array(1,2,3,4) is made. 8 $y[2] = 99; 9 echo $x[2], " ", $y[2]; 10 11 12 function add1ToAll( $data ) { 13 foreach ($data as $k => $val) { 14 $data[$k] += 1; 15 } 16 return $data; 17 } 18 19 echo "before:"; 20 print_r($x); 21 add1ToAll($x); 22 echo "after calling but ignoring return-value:"; 23 print_r($x); 24 $x = add1ToAll($x); 25 echo "after calling and re-assigning the return-value:"; 26 print_r($x); 27 28 // Note that there were *three* array-copies happening in `$x = add1ToAll($x)` -- 29 // One to copy the parameter into the function; one copying the return value back, 30 // and one when assigning the return-value (back) into $x. 31 32 33 34 function add1ToAllByReference( &$data ) { 35 foreach ($data as $k => $val) { 36 $data[$k] += 1; 37 } 38 //return $data; // no need to return a passed-by-reference var. 39 } 40 echo "before:"; 41 print_r($x); 42 add1ToAllByReference($x); 43 echo "after calling but ignoring return-value:"; 44 print_r($x); 45 $x = add1ToAllByReference($x); 46 echo "after calling and re-assigning the return-value:"; 47 print_r($x); 48 49 // print_r( add1ToAllByReference( array(80,81,82,83) ) ); 50 // The above line yields: 51 // Fatal error: Only variables can be passed by reference in lect13b.php on line 50 52 ?> |
This is different from pass-by-reference: In C, when you pass an array to a function, it actually passes a reference to the array — any changes you make to the fields are seen by the caller.
Java uses call-by-value, but object-references are one type of value. (Many people get confused by this, and think that Java passes objects by reference, but it ain't so.) That is, you can pass an int, or a boolean, or a reference-to-String, or reference-to-Puppy.
(example/pictures)
1 (If you want code-inheritance, a common solution is the “delegate pattern” —
class Spymobile extends Vehicle implements Boat, Car { // Two delegate objects, and we'll write our methods to use them as appropriate: Boat b; Car c; void inspect() { b.inspect(); c.inspect(); } void accelerate() { // up to us, } } |
home—lectures—exams—hws—breeze (snow day)
©2012, Ian Barland, Radford University Last modified 2012.Nov.28 (Wed) |
Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |
![]() |