440 likes | 546 Views
Constructors & Co-Reference. Sections 6.1, 6.2, 5.3. Outcomes. Recognize the use of a constructor in code Create constructor stubs and bodies Use an object parameter in a method Overload methods/functions Use a static variable to “count instances”. Object Creation.
E N D
Constructors & Co-Reference Sections 6.1, 6.2, 5.3
Outcomes • Recognize the use of a constructor in code • Create constructor stubs and bodies • Use an object parameter in a method • Overload methods/functions • Use a static variable to “count instances”
Object Creation • Recall the new command Menu m = new Menu(); Random rand = new Random(); TextItemsti = new TextItems(“ArraySearch.dat”); Scanner kbd = new Scanner(System.in); • Sometimes need more information • ti needs a file name, kbd a text source • goes inside parentheses – just like an argument • special method: constructor
Object Initialization • We can specify some extra information with our own objects, too • just need to make the appropriate constructor(s) • example: add title when create Menu Menu m = new Menu(“Main Menu”); Menu sm = new Menu(“Search Menu”); • sets title at creation time – no need to do: m.setTitle(“Main Menu”); sm.setTitle(“Search Menu”);
Constructors Different Again • Class/static methods (functions) double in = Converter.cmToInches(15.0) public static intcmToInches(double cm) • Object methods int choice = m.getChoice() public intgetChoice() • Constructors Menu m = new Menu(“Main Menu”) public Menu(String theTitle) public static returnType public returnType public
Constructor Stub • Menu constructor stub public class Menu{ private final int MAX = 10; private String title = “(no title yet)”; private intnumberOfOptions = 0; private String[] options = new String[MAX]; public Menu(String theTitle) { } … }
Constructor Bodies • Menu constructor replaces call to setTitle • bodies usually just set instance variables public class Menu{ … private String title = “(no title yet)”; … public Menu(String theTitle) { title = theTitle; // or setTitle(theTitle); } … }
Exercise • Make constructor stubs for these commands TextItemsti = new TextItems(“ArraySearch.dat”); Rectangle r = new Rectangle(20.5, 148.3); Student s = new Student(“Alex”, “B.Sc.”); Thingamajig t = new Thingamajig(10, “A”, 44.07, true); Menu m = new Menu(); • But wait! • Menu m = new Menu() worked before! • We didn’t have a constructor back then
A “No Constructor” Constructor • Why did new Room() work before? • if a class has no constructor, Java makes one • it has no arguments and does nothing • Java used that one before we added ours • Why doesn’t it work now? • well, now we have a constructor • it expects to be given a String • so Java doesn’t make the no-argument one
Multiple Constructors • Want to do both Menu m = new Menu(“Main Menu”); Menu sm = new Menu(); sm.setTitle(“Search Menu”); • and maybe even String[] options = new String[]{“This”, “That”, “Both”}; • have you seen that before? Menu mwo = new Menu(“Choose!”, options); • give the title and the options
Stubs for the Three Constructors • Match the arguments public Menu() {} public Menu(String theTitle) {} public Menu(String theTitle, String[] theOptions) {} • Purpose of each is to set instance variables • Menu() sets none • Menu(String) sets the title • Menu(String, String[]) sets title, options andnumberOfOptions
Choosing a Constructor • Java chooses the correct constructor • all by itself Menu w = new Menu(); • the first constructor: Menu() Menu m = new Menu(“Whatever”); • the second constructor: Menu(String) Menu m = new Menu(strVar, strArrVar); • the third constructor: Menu(String, String[]) • just looks at the arguments
Looking at Arguments • Java looks at the number of arguments… new Menu(); new Menu(“A”); new Menu(t, o); • zero, one, two (or even more) • …also looks at the types of the arguments new Menu(“A”); new Menu(26); • Menu(String); Menu(int) • …and the order they appear new Menu(“A”, 3); new Menu(5, “B”); • Menu(String, int); Menu(int, String)
Exercise • Given these constructors • public Thing() • public Thing(String a, int c) • public Thing(String a, String b, int c) • public Thing(String a, String b) • Which constructor gets called? • Thing thing2 = new Thing(“Thing”, 2); • Thing thing3 = new Thing(); • Thing thing1 = new Thing(“Cat”, “Hat”);
Exercise • Someone asks to add a constructor to set the first option of a menu, but not the title Menu oneOption = new Menu(“First Option”); oneOption.setTitle(“Useless Menu”); • Programmer says “Can’t be done.” • Why? Useless Menu 1. First Option
Body of Menu() • Doesn’t need to set any values • everything already given a value • so the body is empty • just like a stub • but it’s FINISHED! public Menu() { } • but it doesn’t have to be empty • sometimes zero-arg constructor will have stuff to do
Body of Menu(String) • Sets the title title = theTitle; • or setTitle(theTitle); • Either will work • second one will automatically check the title • but there are some reasons not to do it that way • but it’s fine for now
Body of Menu(String, String[]) • Sets Menu’s title and options • one possible way: // set the title setTitle(theTitle); // set the title of this Menu // copy in all the options for (inti = 0; i < theOptions.length; i++) { addOption(theOptions[i]); // add option to this Menu } • other ways may be just as good – or even better • depends on what exactly you want!
Location Errors • Don’t use class name for object methods! • Menu.setTitle(theTitle); will not compile • Menu is location of the static methods • there’s no static method named setTitle • Don’t use the calling variable name, either! public Menu(theTitle) { m.setTitle(theTitle); } • doesn’t know the variable m! • and besides, what about sm????
this Location • For object methods leave the location off… setTitle(theTitle); // sets the title of this menu • …or use the location this this.setTitle(theTitle); // sets the title of this menu • whichever object we’re creating • if called from a constructor • same location as this method • if called from a method
this Location • this also works for object variables • in setTitle we could say: this.title = newTitle; • in addOption we could say this.options[this.numberOfOptions] = newOption; this.numberOfOptions++; • but I will typically leave it off… • too much typing! • …unless there’s another object around…
Object Parameters • What if we wanted to check whether one menu was longer than another • for example: if (m1.longerThan(m2)) • where m1 and m2 are both Menus • The stub for this method? public booleanlongerThan(Menu that) { return true; }
Menu is a Data Type • We declare variables to be of type Menu • they are not Strings! • that are not String[]s! • they are Menus! • The method call argument is a Menu, so the method parameter must be a Menu • now we have this Menu and that Menu • the one we asked, and the one we asked it about
The longerThan Method • this Menu is longer if it has more options • look at the number of options for each Menu public booleanlongerThan(Menu that) { if (this.numberOfOptions > that.numberOfOptions) return true; else return false; } • you can call the other Menu whatever you like • I like “that” because of the contrast with “this”
The longerThan Method • PS: remember you can shorten the code in the previous slide to: public booleanlongerThan(Menu that) { return this.numberOfOptions > that.numberOfOptions; } • anyif (…) {return true;} else {return false;} can be shortened like that
Exercise • Suppose we want to ask a Menu whether it has the same title as another Menu? if (m1.hasSameTitleAs(m2)) • Write the method • Note: get the length of a String using its length method: str1.length()
Overloading Methods • All constructors in a class have same name • same as the name of the class • Multiple methods can have same name, too! • consider println System.out.println(“This is a string”); System.out.println(42); System.out.println(3.14); System.out.println(); • that’s 4 different methods with the same name
Overloaded Methods (Stubs) • Need the argument types to be different public void println(String s) {} public void println(int n) {} public void println(double d) {} public void println() {} • can’t repeat the same argument type sequence public void println(String t) {} • doesn’t matter if the parameter names are different • but OK if types are in a different order • just like for constructors!
More Menu Methods • Suppose we sometimes want to change options in the list of options • change “Sort” to “Shuffle” and vice versa • Two ways to do it: • by number: m.changeOption(5, “Shuffle the array”); • by name: m.changeOption(“Sort the array”, “Shuffle the array”);
changeOption Stubs & Plans public void changeOption(int p, String newOpt) { // if p is a valid position in the array of options // set position p to newOpt } public void changeOption(String oldOpt, String newOpt) { // for each valid position in the array of options // if it’s equal to oldOpt // set it to newOpt } A “valid” position is one that’s already filled in. What’s the Java code for is a/each valid position?
Aside: Shuffling an Array • Plan: for each element in the array • pick a random position to swap it with • swap it with that position Random r = new Random(); for (inti = 0; i < a.length; i++) { int n = r.nextInt(a.length); // n is in 0 to a.length – 1 int temp = a[n]; // a[n]’s old value is saved a[n] = a[i]; // a[n]’s value is changed to a[i]’s old a[i] = temp; // a[i]’s value is changed to a[n]’s old } Need to import java.util.Random;
Exercise • Create stubs for the class below: Thingamajig t = new Thingamajig(“Cat”); Thingamajig s = new Thingamajig(5.4); t.makeStuff(“Dog”); t.makeStuff(3); t.makeStuff(“Elephant”, 5); t.makeStuff(s);
Static and Non-Static • static belongs to the class as a whole • Conversion.cmToInches(2.54) static method • a.k.a. class method • public static • non-static belong to an object of the type • m.display() non-static method • a.k.a. object method • public (but not static) • Can have both in one class
Mixing Static and Non-Static • Can have static and non-static methods • object methods and class methods • Can have static and non-static variables • instance variables and class variables • Static variables something about the type itself, not about any particular object • example: keeping count of how many objects of a particular class have been created
Counting Objects • Count how many objects of a class there are • count them as we create them • Maybe for objects that need ID numbers • Student needs a Student # • Car needs a VIN (Vehicle Identification #) • We will count Menus • because we have Menus
Class Variable • Can’t use an object variable to keep track of how many Menu objects there are • each Menu object has its own object variables • different objects would have different counts • would need to change every object each time we create a new object • Need a class (static) variable • it belongs to the class as a whole
Class Variable for Counting • It’s an integer value, starting at zero • make it private so no one else can mess with it • make it static so it belongs to the class • not to any particular object • don’t make it final! • it needs to change every time we make a new Menu • final never changes private static intnumberOfMenus = 0;
Class Method for Asking • Will ask the class (Menu) how many Menu objects there are inthowManySoFar = Menu.getNumberOfMenus(); • Stub? public static intgetNumberOfMenus() { return 0; } • Plan? • return the variable we’re using for the count! public static intgetNumberOfMenus() { return numberOfMenus; }
Aside: Getter Methods • Many methods have just one line • methods that just return the value of a variable (whether class or object variable) very common • these methods called “getters” • usually named get___, with no arguments • where ___ is the name of the variable (capitalized) • numberOfMenus getNumberOfMenus() • title getTitle()
Exercise • Write the following methods (m is a Menu) String t = m.getTitle(); int n = m.getNumberOfOptions();
Keeping Count • Need to add 1 to numberOfMenus every time we create a Menu • that is, every time a constructor gets called • a constructor is called for every object • each object is constructed exactly one time • add this line to every constructor: • remember, we have three different constructors • numberOfMenus++; • or Menu.numberOfMenus++;
Mixing Static and Non-Static • Counting is just one example of mixing static and non-static variables and methods • can easily be adapted to assign a “sequence number” to each object • e.g. Student numbers: Student #1, Student #2, … • create a studentNumberobject variable • set it to the value of the count • this Student object will remember what the count was when it was created
Example Student Class • Program: Student stu = new Student(“Stu”); Student dent = new Student(“Dent”); System.out.println(“Stu is #” + stu.getNumber()); • Student class: private staticnumberOfStudents = 0; private int number = -1; public Student(String theName) { setName(theName); numberOfStudents++; number = numberOfStudents; }