1.00 Lecture 9 Methods and Objects Access Reading for next time: Big Java: sections 7.6, 7.7 Storing weather for a city • We’ll first show an example of storing temperature and precipitation data for cities. – Our classes have some methods with arguments – We’ll examine the methods and arguments: they’ll do what you expect • We’ll then extend our weather example to have each city store a weather information object that collects the weather data in one place – These classes also have methods with arguments – We’ll examine these methods too. They also do what you expect (but your expectations will have to be a bit more sophisticated!) 1 SimpleCity public class SimpleCity { private String name; private double avgTemperature; avgTemperature; private double precipAmt; precipAmt; public SimpleCity(String SimpleCity(String n, double a, double p) { name= n; avgTemperature= avgTemperature= a; precipAmt= precipAmt= p; } public String getName() getName() { return name; } public double getAvgTemperature() getAvgTemperature() { return avgTemperature; avgTemperature; } public void setAvgTemperature(double setAvgTemperature(double t) { avgTemperature= avgTemperature= t; } public double getPrecipAmt() getPrecipAmt() { return precipAmt; precipAmt; } } SimpleWeatherTest public class SimpleWeatherTest { public static void main(String[] args) args) { SimpleCity boston= boston= new SimpleCity("Boston", SimpleCity("Boston", 40.0, 0.0); SimpleCity cambridge= cambridge= new SimpleCity("Cambridge", SimpleCity("Cambridge", 40.0, 0.0); // Now revise the Boston weather, which was corrected boston.setAvgTemperature(41.0); System.out.println System.out.println("Boston: println("Boston: " + boston. boston.getAvgTemperature()); getAvgTemperature()); System.out.println System.out.println("Cambridge: println("Cambridge: "+ cambridge. cambridge.getAvgTemperature()); getAvgTemperature()); } } // What is the output of this program? 2 Passing Arguments SimpleWeatherTest main(…){… City boston= … boston.setAvgTemp(41.0); … Communication only via arg list, return value Argument 1 SimpleCity boston public void setAvgTemp(double t) { // Method makes its own copy // of argument t avgTemperature= t; } Setting the Cambridge temperature would be the same Method/Object Exercise • We now change SimpleCity and SimpleWeatherTest slightly – We rename them City and WeatherTest – We also introduce a simple Weather class – We’ll look at them briefly on the next slides 3 Weather class public class Weather { private double avgTemperature; avgTemperature; private double precipAmt; precipAmt; public Weather(double a, double p) { avgTemperature= avgTemperature= a; precipAmt= precipAmt= p; } public void setAvgTemp(double setAvgTemp(double t) { avgTemperature= avgTemperature= t; } public void setPrecipAmt(double setPrecipAmt(double pr) { precipAmt= precipAmt= pr; } public String toString() toString() { return ("Temperature: "+avgTemperature "+avgTemperature+ avgTemperature+ " ; Precipitation: "+precipAmt "+precipAmt); precipAmt); } } City class public class City { private String name; private Weather cityWeather; cityWeather; public City(String n, Weather c) { name= n; cityWeather= cityWeather= c; } public String getName() getName() { return name; } public Weather getWeather() getWeather() { return cityWeather; cityWeather; } } 4 WeatherTest public class WeatherTest { public static void main(String[] args) args) { Weather today= new Weather(40.0, 0.0); City boston= boston= new City("Boston", today); City cambridge= cambridge= new City("Cambridge", today); // Now revise the Boston weather, which was corrected Weather bostonToday= bostonToday= boston. boston.getWeather(); getWeather(); bostonToday.setAvgTemp(41.0); System.out.println boston. getWeather()); System.out.println("Boston: println("Boston: " + boston .getWeather ()); System.out.println println("Cambridge: System.out. println("Cambridge: "+ cambridge. cambridge.getWeather()); getWeather()); } } Exercise- Weather classes • Download Weather, City, WeatherTest • Import them into Eclipse • Before running them, think about what the output will be • Compile and run them • Is the output what you expected? 5 Objects As Arguments today= Weather today= new Weather(40.0, 0.0); City boston= boston= new City("Boston", today); City cambridge= cambridge= new City("Cambridge", today); // Now revise the Boston weather, which was corrected Weather bostonToday= bostonToday= boston. boston.getWeather(); getWeather(); bostonToday.setAvgTemp(41.0); 40.0 0.0 Weather Objects As Arguments today= Weather today= new Weather(40.0, 0.0); City boston= boston= new City("Boston", today); boston= City cambridge= cambridge= new City("Cambridge", today); // Now revise the Boston weather, which was corrected Weather bostonToday= bostonToday= boston. boston.getWeather(); getWeather(); bostonToday.setAvgTemp(41.0); “Boston” City 40.0 0.0 Weather 6 Objects As Arguments today= Weather today= new Weather(40.0, 0.0); City boston= boston= new City("Boston", today); boston= City cambridge= cambridge= new City("Cambridge", today); cambridge= // Now revise the Boston weather, which was corrected Weather bostonToday= bostonToday= boston. boston.getWeather(); getWeather(); bostonToday.setAvgTemp(41.0); “Boston” City 40.0 0.0 Weather “Cambridge” City Objects As Arguments today= Weather today= new Weather(40.0, 0.0); City boston= boston= new City("Boston", today); boston= City cambridge= cambridge= new City("Cambridge", today); cambridge= // Now revise the Boston weather, which was corrected Weather bostonToday= bostonToday= boston. boston.getWeather(); getWeather(); bostonToday= bostonToday.setAvgTemp(41.0); “Boston” City 40.0 0.0 Weather “Cambridge” City 7 Objects As Arguments today= Weather today= new Weather(40.0, 0.0); City boston= boston= new City("Boston", today); boston= City cambridge= cambridge= new City("Cambridge", today); cambridge= // Now revise the Boston weather, which was corrected Weather bostonToday= bostonToday= boston. boston.getWeather(); getWeather(); bostonToday= bostonToday.setAvgTemp(41.0); “Boston” City 41.0 40.0 0.0 Weather “Cambridge” City When objects are passed as arguments to methods, the method makes a copy of the reference to the object, not a copy of the object! Why? Method Calls With Objects • When passing object references as arguments to a method: – The method makes its own copy of the references – It makes changes to the objects through its local copies of the references – No changes can be made to the references (arguments) • The method can’t change the reference to another object, for example – Results are returned through the return value, which may be an object • When passing built-in data types as arguments to a method: – – – – The method makes its own copy of the built-in variables It makes changes to its local copies only No changes are made to the arguments Results are returned through the return value 8 If you don’t like this… • When you pass an object reference as an argument to a method, the method may make its own local copy of the object: public class SaferCity { private String name; private Weather cityWeather; cityWeather; } public SaferCity(String SaferCity(String n, Weather c) { name= n; double temp= c.getAvgTemperature c.getAvgTemperature(); getAvgTemperature(); double prec= prec= c.getPrecipAmt c.getPrecipAmt(); getPrecipAmt(); cityWeather= cityWeather= new Weather(temp, prec); prec); } public String getName() getName() { return name; } public Weather getWeather() getWeather() { return cityWeather; cityWeather; } // Weather must have methods getAvgTemperature(), getAvgTemperature(), getPrecipAmt() getPrecipAmt() Access: Variables, Methods • Instance and static variables and methods have 4 access modifiers: – Private: Access only to own class’ methods • Data fields should be private, almost always • Other objects of same class can access private variables – Public: Access to all methods, all classes • Methods intended for other class’ use are public • Methods for internal use only are private – Package: Access to methods of classes in same package (a package is a group of classes) • This is the default, alas. Always specify scope explicitly • No ‘package’ keyword; it’s the default with no keyword – Protected: Used with inheritance (covered later) • Like a private variable, except it’s visible to derived or subclasses (and, in Java, to other classes in package) 9 Packages in Eclipse In Eclipse: File -> New -> Package. Type ‘weather’ Use lower case names by convention Create a new class Observation in weather (File -> New -> Class … ) Class Observation package weather; // Eclipse wrote this for you // Cut and paste this from the download, or import it public class Observation { private double humidity; private double cloudCover; cloudCover; public Observation(double h, double c) { humidity= h; cloudCover= cloudCover= c; } public double getHumidity() getHumidity() { return humidity; } public double getCloudCover() getCloudCover() { return cloudCover; cloudCover; } public String toString() toString() { return ("Humidity: "+ humidity+ " ; Cloud cover: "+cloudCover "+cloudCover); cloudCover); } } 10 Add Observation to City • In your default package in Lecture 11: – Modify your City class to also have an Observation object: • • • • Add import weather.*; on 1st line of City.java Add a private Observation obj Modify your constructor Add a getObservation method • We’ll show the solution on the next slide, and then go on to modify WeatherTest to use your new City and Observation Modify WeatherTest • Change WeatherTest, still in the default package, to: – – – – Create a new Observation Place it in Boston and Cambridge Output it (System.out.println) for Boston Remember to import weather.*; on line 1 11 Package access • If we added another class AdvancedObservation to package weather • And we made humidity and cloudCover package access variables by removing the private keyword (in an Observation2 class) – We also remove the getXXX methods as unneeded • Then AdvancedObservation can use Observation data members, such as humidity and cloudCover directly. It can simply say, for an Observation2 object obs: – obs.humidity, or obs.cloudCover as if they were in the AdvancedObservation class Modified Class Observation package weather; public class Observation2 { double humidity; // No keyword means package access double cloudCover; cloudCover; // No keyword means package access public Observation2(double h, double c) { humidity= h; cloudCover= cloudCover= c; } } 12 Class AdvancedObservation package weather; public class AdvancedObservation { double dewpoint; // Package access dewpoint; Observation2 obs; // Package access obs; public AdvancedObservation(double AdvancedObservation(double d, Observation2 o) { dewpoint= dewpoint= d; obs= obs= o; } public String toString(){ toString(){ return ("Humidity: "+obs "+obs.humidity+" obs.humidity+" ; Cloud cover: " + obs. obs.cloudCover+ cloudCover+ " ; Dewpoint: Dewpoint: "+ dewpoint); dewpoint); // We can use obs.XXX obs.XXX directly // Observation2 could use dewpoint directly also } } 13