RU beehive logo ITEC dept promo banner
ITEC 120
2012fall
dbraffitt
ibarland

homeinfolectslabsexamshws
tutor/PIsbreeze (snow day)
Object120 + its docsjava.lang docsjava.util docs

lab08a
static vs non; toString; equals intro
understanding 'cannot be called from non-static context'

Review: Non-static methods:

  1. (a) how to call a static method.
            Song s1 = new Song( "Violet Hill", "Coldplay", 180, true );
    
            // Instead of   fitsOnDisk(s1,2.5), write:
            s1.fitsOnDisk(2.5);
     
  2. How to write a static method.
      /* Instead of:
      static boolean fitsOnDisk(Song thisSong, double freeSpace) {
        return thisSong.length * MB_PER_SEC <= freeSpace;
        }
      We will write:
      */
      static boolean fitsOnDisk( /* Song thisSong, */ double freeSpace) {
        return thisSong.length * MB_PER_SEC <= freeSpace;
        }
     

One common mistake:
When converting to a non-static version, be careful to move the s1 to just before the (immediate) method call:

(We don't ask the Song s1 “hey, can you assert that these two things are equal for me?” — that's not a job that has anything to do with a Song. We do want to ask the song “hey, can you fit onto a disk with 23MB free?”.

If you get the error “unable to call a non-static function from a static context”, what does that mean? What is the “static context” being mentioned?

One student asked about someObject.someStaticMethod(...): it doesn't make sense (you're not passing someObject as an implicit parameter)… and yet, everything works fine. Arg, Java!

equality: two notions

Similar for Robots (and evilCopy); Draw the picture:

  // **Draw pictures** (memory diagrams):
  Robot r1, r2, r3, r4;
  r1 = new Robot("cell phone",true,true);
  r2 = new Robot("cell phone",true,true);
  r3 = r2;
  r4 = r2.evilCopy();
If we mutate r2's weight, then r1 does not change — they are (references to) different objects. But since r2 and r3 are both referring to the same, identical robot, we do see the change using either name:
r2.isEvil = false;
r2.isEvil  // false, as expected.
r1.isEvil // still true, as expected.
r3.isEvil // false!
This is called “aliasing” — having two different references to the same underlying object:
“If Elizabeth Windsor dyes her hair, then the Queen of England's hair-color has changed.”

Note that the same picture holds for Strings, which are objects:

  // **Draw pictures** (memory diagrams):
  String s1, s2, s3;
  s1 = "election";
  s2 = s1;
  s3 = new String("election");

  s1.equals(s2)
  s1.equals(s3)
  s1 == s2
  s1 == s3

What's going on: When comparing two object references, == returns true if (and only if) they reference (point to) the identically-same object.
Equality: intensional ("equals(Object)"; if applied recursively it's a "deep" equality-check) extensional (shallow) ("==").
What `equals` means: If you don't do anything to say otherwise, your own classes have a equals (inherited from java.lang.Object) which just does the same thing == does (?!):
  // Inside class java.lang.Object, deep in the bowels of Java:
  public boolean equals(Object that) { return this == that; }
If you want equals to do something smarter, you have to write it yourself (“overriding the version inherited from Object”). That's what class String does, which is why equals works for Strings.

Three things extending Object120 gave us:

homeinfolectslabsexamshws
tutor/PIsbreeze (snow day)
Object120 + its docsjava.lang docsjava.util docs


©2012, Ian Barland, Radford University
Last modified 2012.Oct.17 (Wed)
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Powered by PLT Scheme