
E-Bookshop-master / uploads / file / Think-Java-How-to-Think-Like-a-Computer-Scientist_(1)
.pdf190 |
Chapter 14. Objects of Arrays |
helper method: Often a small method that does not do anything enormously useful by itself, but which helps another, more useful, method.
14.9Exercises
Exercise 14.1. The goal of this exercise is to implement the shu ing and sorting algorithms from this chapter.
1.Download the code from this chapter from http: // thinkapjava. com/ code/ Card2. java . and import it into your development environment. I have provided outlines for the methods you will write, so the program should compile. But when it runs it prints messages indicating that the empty methods are not working. When you ll them in correctly, the messages should go away.
2.If you did Exercise 12.4, you already wrote randomInt. Otherwise, write it now and add code to test it.
3.Write a method called swapCards that takes a deck (array of cards) and two indices, and that switches the cards at those two locations.
HINT: it should switch references, not the contents of the objects. This is faster; also, it correctly handles the case where cards are aliased.
4.Write a method called shuffleDeck that uses the algorithm in Section 14.2. You might want to use the randomInt method from Exercise 12.4.
5.Write a method called indexLowestCard that uses the compareCard method to nd the lowest card in a given range of the deck(from lowIndex to highIndex, including both).
6.Write a method called sortDeck that arranges a deck of cards from lowest to highest.
7.Using the pseudocode in Section 14.6, write the method called merge. Be sure to test it before trying to use it as part of a mergeSort.
14.9. Exercises |
191 |
8.Write the simple version of mergeSort, the one that divides the deck in half, uses sortDeck to sort the two halves, and uses merge to create a new, fully-sorted deck.
9.Write the fully recursive version of mergeSort. Remember that sortDeck is a modi er and mergeSort is a function, which means that they get invoked di erently:
sortDeck(deck); |
// |
modifies |
existing |
deck |
|
deck = mergeSort(deck); |
// |
replaces |
old deck |
with |
new |
192 |
Chapter 14. Objects of Arrays |
Chapter 15
Object-oriented programming
15.1Programming languages and styles
There are many programming languages and almost as many programming styles (sometimes called paradigms). The programs we have written so far are procedural, because the emphasis is on specifying computational procedures.
Most Java programs are object-oriented, which means that the focus is on objects and their interactions. Here are some of its characteristics of object-oriented programming:
Objects often represent entities in the real world. In the previous chapter, creating the Deck class was a step toward object-oriented programming.
The majority of methods are object methods (like the methods you invoke on Strings) rather than class methods (like the Math methods). The methods we have written so far have been class methods. In this chapter we write some object methods.
Objects are isolated from each other by limiting the ways they interact, especially by preventing them from accessing instance variables without invoking methods.
194 |
Chapter 15. Object-oriented programming |
Classes are organized in family trees where new classes extend existing classes, adding new methods and replacing others.
In this chapter I translate the Card program from the previous chapter from procedural to object oriented style. You can download the code from this chapter from http://thinkapjava.com/code/CardSoln3.java.
15.2Object methods and class methods
There are two types of methods in Java, called class methods and object methods. Class methods are identi ed by the keyword static in therst line. Any method that does not have the keyword static is an object method.
Although we have not written object methods, we have invoked some. Whenever you invoke a method \on" an object, it's an object method. For example, charAt and the other methods we invoked on String objects are all object methods.
Anything that can be written as a class method can also be written as an object method, and vice versa. But sometimes it is more natural to use one or the other.
For example, here is printCard as a class method:
public static void printCard(Card c) { System.out.println(ranks[c.rank] + " of " + suits[c.suit]);
}
Here it is re-written as an object method:
public void print() {
System.out.println(ranks[rank] + " of " + suits[suit]);
}
Here are the changes:
1.I removed static.
2.I changed the name of the method to be more idiomatic.
3.I removed the parameter.
15.3. The toString method |
195 |
4.Inside an object method you can refer to instance variables as if they were local variables, so I changed c.rank to rank, and likewise for suit.
Here's how this method is invoked:
Card card = new Card(1, 1); card.print();
When you invoke a method on an object, that object becomes the current object, also known as this. Inside print, this refers to the card the method was invoked on.
15.3The toString method
Every object type has a method called toString that returns a string representation of the object. When you print an object using print or println, Java invokes the object's toString method.
The default version of toString returns a string that contains the type of the object and a unique identi er (see Section 11.6). When you de ne a new object type, you can override the default behavior by providing a new method with the behavior you want.
For example, here is a toString method for Card:
public String toString() {
return ranks[rank] + " of " + suits[suit];
}
The return type is String, naturally, and it takes no parameters. You can invoke toString in the usual way:
Card card = new Card(1, 1);
String s = card.toString();
or you can invoke it indirectly through println:
System.out.println(card);
196 |
Chapter 15. Object-oriented programming |
15.4The equals method
In Section 13.4 we talked about two notions of equality: identity, which means that two variables refer to the same object, and equivalence, which means that they have the same value.
The == operator tests identity, but there is no operator that tests equivalence, because what \equivalence" means depends on the type of the objects. Instead, objects provide a method named equals that de nes equivalence.
Java classes provide equals methods that do the right thing. But for user de ned types the default behavior is the same as identity, which is usually not what you want.
For Cards we already have a method that checks equivalence: public static boolean sameCard(Card c1, Card c2) {
return (c1.suit == c2.suit && c1.rank == c2.rank);
}
So all we have to do is rewrite is as an object method: public boolean equals(Card c2) {
return (suit == c2.suit && rank == c2.rank);
}
Again, I removed static and the rst parameter, c1. Here's how it's invoked:
Card card = new Card(1, 1);
Card card2 = new Card(1, 1);
System.out.println(card.equals(card2));
Inside equals, card is the current object and card2 is the parameter, c2. For methods that operate on two objects of the same type, I sometimes use this explicitly and call the parameter that:
public boolean equals(Card that) {
return (this.suit == that.suit && this.rank == that.rank);
}
I think it improves readability.
Exercise 15.1. Download http: // thinkapjava. com/ code/ CardSoln2. java and http: // thinkapjava. com/ code/ CardSoln3. java .
CardSoln2.java contains solutions to the exercises in the previous chapter. It uses only class methods (except the constructors).
15.5. Oddities and errors |
197 |
CardSoln3.java contains the same program, but most of the methods are object methods. I left merge unchanged because I think it is more readable as a class method.
Transform merge into an object method, and change mergeSort accordingly. Which version of merge do you prefer?
15.5Oddities and errors
If you have object methods and class methods in the same class, it is easy to get confused. A common way to organize a class de nition is to put all the constructors at the beginning, followed by all the object methods and then all the class methods.
You can have an object method and a class method with the same name, as long as they do not have the same number and types of parameters. As with other kinds of overloading, Java decides which version to invoke by looking at the arguments you provide.
Now that we know what the keyword static means, you have probablygured out that main is a class method, which means that there is no \current object" when it is invoked.
Since there is no current object in a class method, it is an error to use the keyword this. If you try, you get an error message like: \Unde ned variable: this."
Also, you cannot refer to instance variables without using dot notation and providing an object name. If you try, you get a message like \non-static variable... cannot be referenced from a static context." By \nonstatic variable" it means \instance variable."
15.6Inheritance
The language feature most often associated with object-oriented programming is inheritance. Inheritance is the ability to de ne a new class that is a modi ed version of an existing class.
198 |
Chapter 15. Object-oriented programming |
Extending the metaphor, the existing class is sometimes called the parent class and the new class is called the child.
The primary advantage of this feature is that you can add methods and instance variables without modifying the parent. This is particularly useful for Java classes, since you can't modify them even if you want to.
If you did the GridWorld exercises (Chapters 5 and 10) you have seen examples of inheritance:
public class BoxBug extends Bug { private int steps;
private int sideLength;
public BoxBug(int length) { steps = 0;
sideLength = length;
}
}
BoxBug extends Bug means that BoxBug is a new kind of Bug that inherits the methods and instance variables of Bug. In addition:
The child class can have additional instance variables; in this example,
BoxBugs have steps and sideLength.
The child can have additional methods; in this example, BoxBugs have an additional constructor that takes an integer parameter.
The child can override a method from the parent; in this example, the child provides act (not shown here), which overrides the act method from the parent.
And if you did the Graphics exercises in Appendix A, you saw another example:
public class MyCanvas extends Canvas {
public void paint(Graphics g) { g.fillOval(100, 100, 200, 200);
}
}
15.7. The class hierarchy |
199 |
MyCanvas is a new kind of Canvas with no new methods or instance variables, but it overrides paint.
If you didn't do either of those exercises, now is a good time!
15.7The class hierarchy
In Java, all classes extend some other class. The most basic class is called Object. It contains no instance variables, but it provide the methods equals and toString, among others.
Many classes extend Object, including almost all of the classes we have written and many Java classes, like java.awt.Rectangle. Any class that does not explicitly name a parent inherits from Object by default.
Some inheritance chains are longer, though. For example, javax.swing.JFrame extends java.awt.Frame, which extends Window, which extends Container, which extends Component, which extends Object. No matter how long the chain, Object is the common ancestor of all classes.
The \family tree" of classes is called the class hierarchy. Object usually appears at the top, with all the \child" classes below. If you look at the documentation of JFrame, for example, you see the part of the hierarchy that makes up JFrame's pedigree.
15.8Object-oriented design
Inheritance is a powerful feature. Some programs that would be complicated without it can be written concisely and simply with it. Also, inheritance can facilitate code reuse, since you can customize the behavior of existing classes without having to modify them.
On the other hand, inheritance can make programs hard to read. When you see a method invocation, it can be hard to gure out which method gets invoked.
Also, many of the things that can be done with inheritance can be done as well or better without it. A common alternative is composition, where