Download presentation
Presentation is loading. Please wait.
1
CS2013 Lecture 2 Review of OOP
2
Review CS2012 covers a large volume of difficult material. Use the ungraded diagnostic quiz to identify areas you need to review over the weekend. This review covers just the key concepts from CS2012 and those that are critical as foundations for the material in CS2013. I will not review GUIs or JavaFX thoroughly, but talk to me if you did not learn JavaFX in your previous classes. 2
3
Static Vs. Instance Data
Static data fields are controlled by the class, not the object. A static field has only one value for all instances of a class at any point during runtime Instance data fields belong to the object, not the class, so they can have different values for each object. 3
4
Static vs Instance Methods
A static method like main() can be run using the class code without instantiating an object. JOptionPane.showMessageDialog(null, "hey"); Static methods cannot directly instance data unless they have a reference to an instance Instance (non-static) methods can be run only as methods of particular objects instantiated from the class: Scanner sc = new Scanner(); double d = sc.nextDouble(); 4 4
5
Static Methods and Data
package demos; public class Borg { private String name; private static int borgCount; public Borg(String nameIn) { name = nameIn; borgCount += 1; } public void stateName() { System.out.println(name + " of " + borgCount); public static void main(String[] args) { int max = 9; borgCount = 0; Borg[] borgs = new Borg[max]; for (int counter = 0; counter < max; counter++) { String name = String.valueOf(counter + 1); borgs[counter] = new Borg(name); borgs[counter].stateName(); 5
6
Why don’t we just use static methods for everything?
public class Clone{ private String name; public Clone(String nameIn){ name = nameIn; } public static void main(String[] args){ Clone bob = new Clone("Bob"); Clone joe = new Clone("Joe"); Clone mary = new Clone("Mary"); bob.greet(); joe.greet(); mary.greet(); private void greet(){ System.out.println("Hi, my name is " + name); This example uses three instances of the same class, which each have different data. We can run the same method from each object, getting different results for each one. 6 6
7
Public and Private Public data may be accessed directly by any object that has a reference to the current object This means that any other object can change your data in any way that seems appropriate to whoever wrote it This leads to unpredictable behavior, because programmers are almost as crazy as users Private fields and methods may only be used from within the current object Most classes have private data which can be accessed or changed only by using public methods The public methods are part of the object and thus can see or change the private data 7 7
8
Public and Private We can reduce the confusion by providing well-defined interfaces instead of allowing other objects to access our data directly To use an object of a certain class, you only need to know its public methods. You can protect the data in your own classes by allowing it to be changed or accessed only by methods you wrote and chose to make publicly available This principle is called information hiding or encapsulation 8 8
9
Public and Private (American) football includes several ways to score points. The main ones are these: A touchdown scores 6 points A conversion, also called an extra point, scores one point but can only be scored immediately after a touchdown A safety scores 2 points A field goal scores 3 points Note that there is no way to score four, five, seven, etc. points at once 9 9
10
Public and Private public class FootballScore {
// models the score for one team in a game of American Football private int score; public int getScore() { return score; } public void touchdown() { score += 6; public void extraPoint() { score += 1; public void safety() { score += 2; public void fieldGoal() { score += 3; 10 10
11
Public and Private How the private data / public methods architecture benefits FootballScore: If external objects (say, a FootballGame object) could arbitrarily change the score in FootballScore, buggy or malicious code could interfere with the functioning of the class for example, by adding 5 to the score or dividing it by 2, changes that are invalid in American Football. this kind of problem is hard to find and extremely hard to fix, since the bad code was probably written by someone else In FootballScore, the available ways to change the score are limited to the ways points can actually be scored in football If anything else needs to be done when the score changes, like updateScoreboard(); or notifyBookmaker(); the author of FootballScore can take responsibility for making sure the public methods trigger it 11 11
12
Public and Private How the private data / public methods architecture benefits objects that use FootballScore: Other objects do not have to understand the internal functioning of FootballScore They only need to know that they can find out the score by calling getScore() and can deal with scoring events by calling, for example, touchdown(). If you decide to change the design of FootballScore, nothing in any other class needs to change as long as the public interface remains the same. This will become very important as your classes get more sophisticated. Suppose you write a class with a method that determines whether or not a touchdown was actually scored. You may sometimes need to change the algorithm used by the method (eg, to use new electronic sensors or to accommodate rule changes in the sport.) As long as the method signature remains the same, other objects don't need to understand anything about it or even know when you change it. 12 12
13
Lists A list is a data type that stores a finite. ordered collection of values, in which the same value may occur more than once Unlike an array, a list can contain a varying number of items. This is very important for memory management, sorting and many other key areas of programming. There are many kinds of lists available in Java, and you can program many other types yourself Memorize this! 13
14
List Methods Here are some of the key List methods
add() adds an item to the end of the list get(int position) gets a reference to the item at the specified position in the list isEmpty() returns a boolean that indicates just what it sounds like size() shows the number of items in the list clear() deletes all items from the list 14
15
List Algorithms Algorithms that iterate through lists, doing some kind of processing on each value, are very common. Finding the total, average, least, or greatest values in a list is similar to doing the same in an array double[] sizesArray = {6.5, 9.0, 10.0, 8.5, 7.5, 11.0, 10.5}; List<Double> shoeSizes = new ArrayList<Double>(); public double findAverageInListOfDoubles(List<Double> list){ double total = 0; for(Double d: list) total += d; return total / list.size(); } Algorithms like this will be important with many new data structures we will study this term. 15
16
Constructors Constructor method headers look like this:
public ClassName(parameters){} By convention, if programmer-defined constructors are present, they are the first methods listed in a class. A class may have more than one constructor (“constructor overloading”) as long as they take different arguments If you write one or more constructors, the compiler does not supply an implicit constructor. If you want one, you must write it yourself, which is very easy: public ClassName(){} For example, public Student(){} 17 17
17
Creating an object An object can be created using a no-parameter constructor like this: access modifier classname objectname = new classname(); For example, private Student mary = new Student(); Note that Student is the name of a class mary is a variable whose value is a reference to the object we created. The value of the variable mary is the address of the memory location where the data for the object starts The data type of the variable mary is Student private means that the variable mary is only visible from this object. 18 18
18
Composition An object can contain references to data values that are objects of other types. This is called Composition You did this as soon as you wrote a class with a Scanner or a String the College class in the example from the last lecture contained a list of Departments, and Department contained a list of Courses. "Compose" is used to mean "create something out of different existing elements" similar to its use in "composite rock"
19
Composition public class Student{ private String name;
private Double gpa; public Student(String nameIn, Double gpaIn) { name = nameIn; gpa = gpaIn; } public String toString() { return "Name: " + name + "; GPA: " + gpa; public class GradeBook { List<Student> students = new ArrayList<Student>(); public void addStudent(String name, double gpa) { students.add(new Student(name, gpa)); public void showGrades(){ //[code omitted] GradeBook contains an array list of Students Student contains a Double and a String Hierarchies like this can be of any depth.
20
Inheritance Classes often have natural hierarchies, which can be defined in terms of data or in terms of functionality The simplest form of hierarchy is general-to- specific 21
21
Inheritance All vehicles have some variables in common weight source of locomotion manufacturer Motor vehicles are a subset of vehicles, and they have additional data fields Engine displacement Fuel type Trucks are a subset of motor vehicles, and they have yet more data fields Hauling capacity Etc 22
22
Inheritance We can model this kind of general-to-specific hierarchy using class inheritance “Super” means above, as in supervisor. “Sub” means under or below, as in submarine. A subclass is a class which is a more specific form of some other class, which we call its superclass Superclasses are more abstract than their subclasses The terms parent and child are sometimes used in place of superclass and subclass. To define a class as a subclass of a superclass, use the extends keyword. See the examples below
23
Inheritance Hierarchy
A class can inherit from a hierarchy of superclasses, in the same way you have parents, grandparents, great-grandparents, etc. All Java classes are subclasses of Object. Object is, for example, where the original forms of toString() is defined. However, most other classes do not inherit directly from Object. Here is the class hierarchy for OutOfMemoryError java.lang.Object java.lang.Throwable java.lang.Error java.lang.VirtualMachineError java.lang.OutOfMemoryError
24
Inheritance Subclasses inherit the methods and variables of their superclasses. Subclasses can add variables, constants, and methods which are not present in their superclasses.
25
Overriding Subclasses can also replace methods inherited from superclasses with their own methods. This is called overriding. toString()! Use annotation Superclass methods must be public or protected; can’t override private methods Subclass constructors call superclass constructors. If superclass has a no-argument constructor, it is called by default by a no- argument subclass constructor
26
Inheritance package vehicles; public class Vehicle {
protected double weightInKg; protected double speedInKmPerHr = 0; // a new vehicle should stop after it rolls off the assembly line protected Direction direction = new Direction(); // avoid null pointer exceptions by giving new vehicle the default direction 0, 0, 0 public Vehicle() { } public Vehicle(double weightInKgIn) { weightInKg = weightInKgIn; public void steer(double bearing, double z) { direction.setDirection(bearing, z); public void accelerate(double speedIncrement) { speedInKmPerHr += speedIncrement; public String toString() { return "vehicle weighs " + weightInKg + " kg: is going " + speedInKmPerHr + ": " + direction.toString();
27
Inheritance package vehicles; public class Direction {
private double bearing, z; public Direction(){} public Direction(double bearingIn, double zIn){ setDirection(bearing, z); } public void setDirection(double bearingIn, double zIn){ bearing = bearingIn; z = zIn; public double getBearing() { return bearing; public double getZ() { return z; public String toString(){ return "bearing: " + bearing + ": z: " + z;
28
Inheritance package vehicles;
public class MotorVehicle extends Vehicle { protected double engineDisplacementInCc; protected String fuelType; protected String manufacturer; public MotorVehicle(){} public MotorVehicle(double weightInKgIn, String manufacturerIn, double displacementIn, String fuelTypeIn) { super(weightInKgIn); manufacturer = manufacturerIn; engineDisplacementInCc = displacementIn; fuelType = fuelTypeIn; } public double getEngineDisplacementInCc() { return engineDisplacementInCc; public String getFuelType() { return fuelType; public String getManufacturer() { return manufacturer; // this method is unique to MotorVehicles, not common to all vehicles public void register() { System.out.println("Registered " + manufacturer + " vehicle with DMV"); public String toString() { return "manufacturer: " + manufacturer + "engine displacement: " + engineDisplacementInCc + ": fuelType: " + fuelType + ": " + super.toString();
29
Inheritance package vehicles; public class Car extends MotorVehicle {
private String licensePlateNumber; public Car(double weightInKgIn, String manufacturerIn, double displacementIn, String fuelTypeIn, String licensePlateNumberIn){ super(weightInKgIn, manufacturerIn, displacementIn, fuelTypeIn); licensePlateNumber = licensePlateNumberIn; } public String getLicensePlateNumber() { return licensePlateNumber; public void setLicensePlateNumber(String licensePlateNumber) { this.licensePlateNumber = licensePlateNumber; public String toString() { return manufacturer + " car with plate " + licensePlateNumber + " and engine displacement " + engineDisplacementInCc + " cc " + fuelType + " engine weighs " + weightInKg + " kg and is going " + speedInKmPerHr +" KPH " + direction.toString();
30
Inheritance package vehicles;
public class Motorcycle extends MotorVehicle { private double volumeInDecibels; public Motorcycle(double weightInKgIn, String manufacturerIn, double displacementIn, double volumeInDecibelsIn) { super(); // note the difference between these assignments and the way the same task is done in the Car constructor. // This way is simpler, but might miss or require duplication of initialization logic in the superclass constructors. manufacturer = manufacturerIn; weightInKg = weightInKgIn; engineDisplacementInCc = displacementIn; fuelType = "gasoline"; speedInKmPerHr = 0; volumeInDecibels = volumeInDecibelsIn; } public double getVolumeInDecibels() { return volumeInDecibels; public void setVolumeInDecibels(double volumeInDecibels) { this.volumeInDecibels = volumeInDecibels; public String toString() { return manufacturer + " motorcycle with a " + engineDisplacementInCc + " cc " + fuelType + " engine weighs " + weightInKg + " kg and is going " + speedInKmPerHr + " KPH " + direction.toString() + " making noise at " + volumeInDecibels + " db";
31
Inheritance package vehicles; public class Driver {
public static void main(String[] args) { Vehicle shredder = new Car(1000, "Mazda", 1900, "gasoline", "ABC-123"); System.out.println(shredder); shredder.accelerate(20); shredder.steer(100, 0); System.out.println(); Vehicle hindenburg = new Motorcycle(240, "BMW", 594, 80); hindenburg.steer(70, 0); hindenburg.accelerate(90); System.out.println(hindenburg); Vehicle porky = new Motorcycle(400, "Harley-Davidson", 1200, 150); porky.accelerate(150); porky.steer(180, 45); System.out.println(porky); }
32
Concrete means particular or tangible, not abstract.
Inheritance Concrete means particular or tangible, not abstract. Originally meant solidified or hardened. The building material was named because it has this quality The classes in the previous examples were concrete classes, ones that can be instantiated 33
33
Classes may be abstract
Inheritance Classes may be abstract An abstract class cannot be instantiated, but it can have subclasses that are concrete. Abstract classes may contain data fields that will be common to all subclasses 34
34
Inheritance Abstract classes may define concrete methods, but they may also declare abstract methods An abstract method isn't defined (written) in the class, but must be defined in a subclass Subclasses that are also abstract can define the method or ignore it, leaving it to be defined in their own subclasses. A concrete class may inherit or override concrete method definitions from its superclass(es) A concrete class must define any methods which are abstract in its superclass hierarchy 35
35
Syntax for abstract method:
Inheritance Syntax for abstract method: access modifier abstract return type name(); For example: protected abstract void accelerate(double speedIncrement); Syntax to implement a method that is abstract in the superclass: Just notation above the method code: @Override protected void accelerate(double speedIncrement){ speedInKmPerHr+=speedIncrement; } 36
36
Inheritance Use an abstract class when you expect to create subclasses that will implement some methods identically but other methods in different ways. If you don’t need any data fields and don’t need to define any methods, use an interface instead. Implementation of multiple subclasses of the same class is another form of polymorphism. 37
37
Inheritance package vehicleswithabstractclass;
public abstract class Vehicle { protected double weightInKg; protected double speedInKmPerHr = 0; // a new vehicle should stop after it rolls off the assembly line protected Direction direction = new Direction(); // avoid null pointer exceptions by giving new vehicle the default direction 0, 0, 0 public Vehicle() { } public Vehicle(double weightInKgIn) { weightInKg = weightInKgIn; public abstract void steer(double bearing, double z); public abstract void accelerate(double speedIncrement); public String toString() { return "vehicle weighs " + weightInKg + " kg: is going " + speedInKmPerHr + ": " + direction.toString(); 38
38
Inheritance 39 package vehicleswithabstractclass;
public abstract class MotorVehicle extends Vehicle { protected double engineDisplacementInCc; protected String fuelType; protected String manufacturer; public MotorVehicle(){} public MotorVehicle(double weightInKgIn, String manufacturerIn, double displacementIn, String fuelTypeIn) { super(weightInKgIn); manufacturer = manufacturerIn; engineDisplacementInCc = displacementIn; fuelType = fuelTypeIn; } public double getEngineDisplacementInCc() { return engineDisplacementInCc; public String getFuelType() { return fuelType; public String getManufacturer() { return manufacturer; // this method is unique to MotorVehicles, not common to all vehicles public void register() { System.out.println("Registered " + manufacturer + " vehicle with DMV"); public String toString() { return "manufacturer: " + manufacturer + "engine displacement: " + engineDisplacementInCc + ": fuelType: " + fuelType + ": " + super.toString(); @Override public void steer(double bearing, double z) { // supply code to steer like a motor vehicle // accelerate() is still abstract here 39
39
Inheritance 40 package vehicleswithabstractclass;
public class Car extends MotorVehicle { private String licensePlateNumber; public Car(double weightInKgIn, String manufacturerIn, double displacementIn, String fuelTypeIn, String licensePlateNumberIn){ super(weightInKgIn, manufacturerIn, displacementIn, fuelTypeIn); licensePlateNumber = licensePlateNumberIn; } public String getLicensePlateNumber() { return licensePlateNumber; public void setLicensePlateNumber(String licensePlateNumber) { this.licensePlateNumber = licensePlateNumber; public String toString() { return manufacturer + " car with plate " + licensePlateNumber + " and engine displacement " + engineDisplacementInCc + " cc " + fuelType + " engine weighs " + weightInKg + " kg and is going " + speedInKmPerHr +" KPH " + direction.toString(); @Override public void accelerate(double speedIncrement) { // supply code to accelerate like a car 40
40
Inheritance 41 package vehicleswithabstractclass;
public class Motorcycle extends MotorVehicle { private double volumeInDecibels; public Motorcycle(double weightInKgIn, String manufacturerIn, double displacementIn, double volumeInDecibelsIn) { super(); // note the difference between these assignments and the way the same task is done in the Car constructor. // This way is simpler, but might miss or require duplication of initialization logic in the superclass constructors. manufacturer = manufacturerIn; weightInKg = weightInKgIn; engineDisplacementInCc = displacementIn; fuelType = "gasoline"; speedInKmPerHr = 0; volumeInDecibels = volumeInDecibelsIn; } public double getVolumeInDecibels() { return volumeInDecibels; public void setVolumeInDecibels(double volumeInDecibels) { this.volumeInDecibels = volumeInDecibels; public String toString() { return manufacturer + " motorcycle with a " + engineDisplacementInCc + " cc " + fuelType + " engine weighs " + weightInKg + " kg and is going " + speedInKmPerHr + " KPH " + direction.toString() + " making noise at " + volumeInDecibels + " db"; @Override public void accelerate(double speedIncrement) { // accelerate like a motorcycle 41
41
Inheritance package vehicles;
public abstract class Spacecraft extends Vehicle { // this class could have a hierarchy of abstract and concrete classes under it } 42
42
Inheritance package vehicleswithabstractclass; public class Driver {
public static void main(String[] args) { Vehicle shredder = new Car(1000, "Mazda", 1900, "gasoline", "ABC-123"); System.out.println(shredder); shredder.accelerate(20); shredder.steer(100, 0); System.out.println(); Vehicle hindenburg = new Motorcycle(240, "BMW", 594, 80); hindenburg.steer(70, 0); hindenburg.accelerate(90); System.out.println(hindenburg); Vehicle porky = new Motorcycle(400, "Harley-Davidson", 1200, 150); porky.accelerate(150); porky.steer(180, 45); System.out.println(porky); } 43
43
You can't instantiate an abstract class:
Inheritance You can't instantiate an abstract class: 44
44
Inheritance A concrete class must have a definition for each inherited method. If the method was abstract in the last superclass, it must be defined in the new class: 45
45
More On Inheritance Usually a bad idea 46
46
Inheritance You can use a reference variable to get access to public methods of the variable's type and supertypes. Using methods of subtypes of the variable's type requires a cast and is usually a bad idea. This is true even though you instantiate an object of the subclass and make the variable reference it. public class Motorcycle extends MotorVehicle { private boolean sidecarPresent; … stuff omitted public void installSidecar(){ // this is a method of motorcycle. Its superclasses don't know about it sidecarPresent = true; } … 47
47
Inheritance These are both dicy ideas! 48
48
Types and Data Structure Parameters
Arrays and Lists (and also other data structures you will study in CS 2013) can be parameterized by abstract classes An abstract class can not be instantiated. Therefore, an array or list whose type is an abstract class will contain objects of concrete subclasses of the abstract class. mix different subclasses in any combination 49
49
Types and Data Structure Parameters
package vehicles; public class Miata extends Car { public Miata(double weightInKgIn, double displacementIn) { super("Mazda", weightInKgIn, displacementIn, "gasoline"); } public String toString() { return "Miata with a " + engineDisplacementInCc + " cc gasoline engine weighs " + weightInKg + " kg and is going " + speedInKmPerHr +" KPH " + direction.toString(); 50
50
Types and Data Structure Parameters
package vehicles; public class ShrinerMobile extends Car { public ShrinerMobile(double weightInKgIn, double displacementIn, String fuelTypeIn) { super("Shriners' Lodge #1", weightInKgIn, displacementIn, "gasoline"); } public String toString() { return "ShrinerMobile with a " + engineDisplacementInCc + " cc gasoline engine weighs " + weightInKg + " kg and is going " + speedInKmPerHr +" KPH " + direction.toString(); 51
51
Types and Data Structure Parameters
52
52
Breaking Down At The Interfaces
Software is said to "break down at the interfaces." You can write a class that does a good job of modeling a savings account Somebody else will do a good job writing a class that models a bank The hard part is making them work together 53
53
Interface The word interface has at least four different meanings in programming: The relationship between different parts of your application, the meeting place between different components, the ways other objects can interact with instances of your classes. Java interface, described below The set of public methods a class provides (exposes) to client code (code that will rely on your code.) This may be defined by a Java interface, a superclass, or just by the public methods you write for the class. User Interface (UI); the ways provided for a user to provide input and get output. 54
54
Need For Java Interfaces
Inheritance is very powerful and can be used well where Subclasses will have some similarities and some differences Subclasses can be grouped hierarchically MotorVehicle Vs. Spacecraft Subclasses will share variables But class hierarchies can be confusing since methods might be defined at any point in the hierarchy, they can be hard to change without creating unanticipated consequences 55
55
Need For Java Interfaces
Java interfaces meet some of the same needs in a different and simpler way Interfaces provide another form of polymorphism. If you are programming a furnace, you need a heatAir() method. However, the internal workings of the method will differ depending on whether you are programming a gas furnace or an oil one. Interfaces contain method declarations and may contain constants No method definitions No variables Interfaces can’t declare private or protected methods, just public ones (that's why they're called that!) 56
56
Interface Syntax Syntax for defining a Java interface:
Access modifier interface name{ final declarations method declarations } For example: public interface Vehicle { public static final double KMTOMILES = .609; public void accelerate(double speedIncrementInKmPH); public double getSpeedInKmPH(); public void steer(Direction d); 57
57
Need For Interfaces Classes implement Java interfaces. This is declared in the class header: public class MyClass implements MyInterface { eg, public class Car implements Vehicle { The distinction between interface (in the sense of "the ways other objects can interact with objects of your class) and implementation is very important in OOP. A class can implement any number of interfaces 58
58
Implementing Interfaces
A class that implements an interface must implement the methods declared in the interface Thus, if a class implements a particular interface, we know that we can call certain methods on objects of the class. We don’t care that the methods may work differently for different implementations of the interface. Here's another way to make the last point. Different classes that implement the interface may use methods whose internal workings are completely different, as long as they have the signature defined in the interface 59
59
Implementing Interfaces
Implementations of methods required by an interface should use annotation: @Override public void setLocation(String location){ this.location = location; } 60
60
Not Breaking Down At The Interfaces
Other objects that deal with objects of your class should only have to know the public interface, not the internal workings of your class Reduce what other programmers need to learn (or you need to remember) in order to use your classes Minimize problems at interfaces You can change the internal workings of your class without any problems if the interface stays the same. 61
61
Not Breaking Down At The Interfaces
Consider a WeatherReport class and a WeatherBalloon class. A WeatherReport should be able to get the barometric pressure from a WeatherBalloon by just calling an accessor method. It shouldn’t be dependent on the particular way WeatherBalloon determines what the pressure is. WeatherReport's programmer doesn’t need to learn how the measurement is made WeatherBalloon's programmer can change the method for determining pressure without affecting WeatherReport at all. Compare this to a computer storing data in permanent storage. I should be able to swap out my hard drive and controller for an SSD drive and controller without affecting the CPU, operating system, etc. 62
62
Not Breaking Down At The Interfaces
Consider an application that monitors monster attacks. We need to track both various species of monsters, like zombies, and unique monsters, like Godzilla and the Jersey Devil ( We also need to be able to track new types of monsters we don’t even know about yet. Although there are many types of monsters, all monsters can do these things: tell us their names change locations tell us their origin stories rampage 63
63
List Parameterized by an Interface
List<Monster> monsters = new ArrayList<Monster>(); Monster ebenezer = new Zombie("New Orleans"); Monster godzilla = new UniqueMonster("Godzilla", "radioactive breath of fire", "Tokyo", "ancient sea monster awakened from millennia of sleep by radioactive fallout after " + "World War II"); // if the type in the list or array is an interface, we can add objects of any class that implements the interface monsters.add(ebenezer); // ebenezer is a Zombie monsters.add(godzilla); // godzilla is a UniqueMonster 64
64
Monster Interface package monsters; public interface Monster {
public void setName(String name); public String getName(); public void setLocation(String location); public void rampage(); public String getOriginStory(); } 65
65
66 package monsters; public class Zombie implements Monster{
private static int zombieCount; // since zombieCount is static, we will get the same zombieCount from any Zombie private String name; private String location; public Zombie(String location){ this.name = "Zombie # " + String.valueOf(zombieCount); zombieCount++; this.location=location; } @Override public void setName(String name) { this.name = name; public String getName() { return name; public void rampage() { System.out.println(name + " joins a herd of zombies who attack citizens of " + location + " and eat their brains"); public String getOriginStory() { return "former human being who was raised from the dead by a magical spell spread by the bite of " + "other zombies."; public void setLocation(String location) { this.location = location; 66
66
67 package monsters; public class UniqueMonster implements Monster{
private String name; private String weapon; private String location; private String originStory; public UniqueMonster(String name, String weapon, String location, String originStory) { this.name = name; this.weapon = weapon; this.location = location; this.originStory = originStory; } @Override public void setName(String name) { public void setLocation(String location){ public void rampage() { System.out.println(name + " destroys " + location + " with " + weapon); public String getOriginStory() { return originStory; public String getName() { return name; 67
67
68 package monsters; import java.util.ArrayList;
import java.util.List; public class MonsterAttackDriver { public static void main(String[] args) { List<Monster> monsters = new ArrayList<Monster>(); Monster m1 = new UniqueMonster("Godzilla", "radioactive breath of fire", "Tokyo", "ancient sea monster awakened from millennia of sleep by radioactive fallout after World War II"); monsters.add(m1); // here is a more concise way to create and object and add it to the list monsters.add(new UniqueMonster("Jersey Devil", "claws", "Princeton", "giant " + "batlike creature born to a cursed farmer in the 1700s")); Monster m = new Zombie("New Orleans"); monsters.add(m); for (int counter = 0; counter < 3; counter++) { m = new Zombie("London"); // reuse the Monster variable from a few lines back } for (Monster z : monsters) { System.out.println(z.getName() + " is a(n) " + z.getOriginStory()); z.rampage(); System.out.println(); 68
68
Code To Interface, Not The Implementation
In this saying, "interface" means the public methods of a general, high-level class. In Java, this could be either a superclass or Java interface Use variables of the most abstract type available Use interface or superclass methods rather than methods that are unique to particular concrete classes whenever possible Coding to particular implementations, as opposed to interfaces, exposes you to the risk that your code will break when some other implementation changes. This is *very* dangerous because you may not even know when the other classes change. Coding to the interface also makes your code more modular. If you rely on well-defined interfaces, you can more easily swap out parts of your code later or determine which implementations of an interface at runtime. 69
69
Code To Interface, Not Implementation
70
70
Interface vs. Abstract Class
Suppose you need two different versions of a scheduling system for emergency rooms. The following methods will work the same way in both versions: public void addToWaitList(Patient p) public void showWaitList() However, the method: public Patient selectNextPatientFromWaitList() Will work differently in the two implementations. In the Canadian version, the method will search the list for the sickest patient and select him or her. In the US version, the method will search the list for the richest patient and select him or her. This is a case for an abstract class, because much of the code will be the same for both implementations, so it can be coded only once, in the superclass
71
Interface vs. Abstract Class
Now suppose you need two different versions of CoffeeMaker. The first type heats water by using electrical coils and brews by directing the hot water through a filter which contains the coffee grounds. The second type uses a gas burner to heat water containing coffee grounds, then filters the grounds out. Both versions of CoffeeMaker need the methods heatWater() filter() But each performs these operations differently. This is a case for an interface, since none of the implementing code in the methods will be the same. Interfaces are also often used for incidental add-on functionality, as with the Comparable interface we will study in the next lecture. They are better suited for this kind of thing than abstract or concrete superclasses since classes may implement any number of interfaces as you choose.
72
Inner and Anonymous Classes
An inner class is coded literally inside the outer classes, before the closing curly brace. Anonymous inner classes, which almost always implement interfaces, are very common in GUI programming and client-server apps (that's nearly everything these days!) When we cover GUIs, you will need to understand anonymous classes. 73
73
Simulators Imagine you need data to test software that will be used to process real-world measurements, like the ages of college students Sometimes you might want linearly-distributed data, but Gaussian (normal) distributions are often more realistic Random.nextGaussian() returns a double from a normal distribution with standard deviation = 1 and mean = 0. Multiply it by the desired STD and then add the desired mean
74
package simulator; import java.util.Arrays; public class GradeSimulator { private double average; private double std; private int classSize; private double[] grades; private final double MINGRADE = 0; private final double MAXGRADE = 100; public enum GradingType { UNIFORM, GAUSSIAN }; public GradeSimulator(double avgIn, double stdIn, int classSizeIn) { average = avgIn; std = stdIn; classSize = classSizeIn; } public static void main(String[] args) { GradeSimulator grd = new GradeSimulator(80d, 10d, 20); grd.grade(GradingType.UNIFORM); grd.grade(GradingType.GAUSSIAN); private void grade(GradingType type) { RandomArrayGenerator sim = new RandomArrayGenerator(); if (type == GradingType.UNIFORM) grades = sim.getLinearData(classSize, MINGRADE, MAXGRADE); if (type == GradingType.GAUSSIAN) grades = sim.getGaussianData(average, std, classSize, MINGRADE, MAXGRADE); System.out.println("\nData using distribution type: " + type + "\n"); for (int i = 0; i < grades.length; i++) { System.out.print("Student #" + i + " received a grade of "); System.out.printf("%3.1f\n", grades[i]); Arrays.sort(grades); System.out.println("Here are the sorted values from the simulator:"); for (double d : grades) System.out.printf("%3.1f\n",d);
75
package simulator; import java.util.Random; public class RandomArrayGenerator { private double[] nums; public double[] getGaussianData(double mean, double std, int count, double min, double max) { Random r = new Random(); nums = new double[count]; double randDoub; for (int counter = 0; counter < nums.length; counter++){ randDoub = r.nextGaussian() * std + mean; // it's pretty hard to set limits for the values in a good way, so here is a hacky way. if(randDoub > max) randDoub = max; if(randDoub < min) randDoub = min; nums[counter] = randDoub; } return nums; public double[] getLinearData(int count, double min, double max) { // it would be better to make sure max < min first, but I am not implementing this in this example randDoub = r.nextDouble() * (max - min) + min;
76
Separate Things That Are Likely To Change Independently
GradeSimulator is domain-specific (only useful for a narrow type of problem, in this case grading schoolwork) randomArrayGenerator, on the other hand, does not contain anything that shows it is from an application that simulates grading. It could be used to generate test data for a very wide variety of problems This is an example of an important principle in software engineering. Separate the general from the specific, and separate things you can probably reuse from things you can't. If two things are likely to change independently of each other, don’t combine them.
77
ClickCounter This application uses GUI components and EventHandlers to do the following: Place a grid of buttons on a GridPane Place a Label into in an Hbox (one-row Pane) indicating how many buttons are currently clicked Attach EventHandlers to each button that track whether the button is currently clicked or not clicked and update the count displayed on the Label Add both Panes to a BorderPane Notice the use of String.valueOf() to convert numeric values to Strings for display in labels
78
Click Counter public class ClickCounter extends Application {
private int numClicked; @Override public void start(Stage primaryStage) throws Exception { BorderPane bp = new BorderPane(); bp.getStyleClass().add("grid"); GridPane gp = new GridPane(); Label clickedLabel = new Label("Buttons Clicked: "); clickedLabel.getStyleClass().add("clickedLabel"); Label numClickedLabel = new Label("0"); numClickedLabel.getStyleClass().add("clickedLabel"); HBox clickedCounterBox = new HBox(); clickedCounterBox.getStyleClass().add("clickedBox"); clickedCounterBox.getChildren().add(clickedLabel); clickedCounterBox.getChildren().add(numClickedLabel); Scene sc = new Scene(bp); sc.getStylesheets().add("styles/style.css"); numClicked = 0; for (int rowCounter = 0; rowCounter < 10; rowCounter++) for (int colCounter = 0; colCounter < 10; colCounter++) { }
79
Click Counter Button b = new Button("Unclicked"); b.setMinWidth(150);
b.getStyleClass().add("button"); b.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() { Boolean clicked = false; @Override public void handle(Event event) { if (clicked == true) { clicked = false; b.setText("Unclicked"); numClicked--; } else { clicked = true; b.setText("Clicked"); numClicked++; } numClickedLabel.setText(String.valueOf(numClicked)); }); gp.add(b, colCounter, rowCounter); bp.setTop(clickedCounterBox); bp.setBottom(gp); primaryStage.setScene(sc); primaryStage.show();
80
CSS .pane{ -fx-font-size: 250%; -fx-padding: 20px; } .grid{
.clickedLabel{ -fx-background-color: #00FFFF; .clickedBox{ -fx-alignment: center;
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.