Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Lecture Notes
CPSC 326 (Fall 2011)
Today ...
• Java (cont.)
• Start on PL implementation
Reading
• Ch 4
Reminders
• HW 8a and b due
• Proj 1 due
• Proj 2 out
S. Bowers
1 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Arrays
Statically defining an array
int[] theArray = {100, 10, 1000, 20, 200};
Accessing elements
theArray[0];
theArray[1];
theArray[5];
// returns 100
// returns 10
// IndexOutOfBounds Exception (error)
Use length to get the length of an array
len = theArray.length;
Using arrays in loops
for(int i = 0; i < theArray.length; i++)
System.out.println(theArray[i]);
• Or just use a foreach loop
for(int x : theArray)
System.out.println(x);
• Much cleaner ... use foreach whenever possible
S. Bowers
2 of 13
Lecture Notes
CPSC 326 (Fall 2011)
More on declaring Java arrays
• These are all equivalent
int[] theArray;
int [] theArray;
int theArray[];
int theArray [];
// the "standard" approach
// C++ style
• This is not allowed in Java:
int[5] theArray;
• Instead do this:
int[] theArray = new int[5];
• note each element is initialized to a default value
• also, once you declare an array, you cannot initialize it again with a constant
• but you can do this:
theArray = {1, 2, 3, 4, 5};
theArray = new int[] {1, 2, 3, 4, 5};
// compile error
// this works
Array variables are references to array objects
• This means we have to be careful with assignment
int[] smallPrimes = {2, 3, 5, 7};
int[] luckyNumbers = smallPrimes;
luckyNumbers[3] = 8;
S. Bowers
// changes smallPrimes!
3 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Strings
In Java, String (objects) are immutable
• This means String operations always return new strings
• E.g., concatenation (str1 + str2 returns a new String)
• Lots of String helper functions (substring, trim, toLowerCase, indexOf, ...)
S. Bowers
4 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Objects
When you create a new object in Java
• The JVM allocates memory space on the heap
• All Java objects live in the heap
• When an object isn’t needed, the JVM frees up the space for you
• This is done via automatic “garbage collection”
• The garbage collector (JVM) looks for unreachable objects
Example:
1.
2.
3.
4.
5.
6.
7.
8.
Book b = new Book();
Book c = new Book();
Bood d = c;
c = new Book();
d = c;
d = null;
d.getTitle();
b = null;
//
//
//
//
//
//
d references same object as c
c now references a new object
now there is a non-referenced object!
d is now a "null" reference
this generates a NullPointerException
old b object can now be garb. collected
Arrays of object references
Q: What happens to the heap after this statement?
Book[] books = new Book[3];
• Each element in the books array is a null reference
Q: What happens if we call: books[1].turnPage()
• We get a NullPointerException!
S. Bowers
5 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Class Inheritance
Subclassing is done using the “extends” keyword
public class Ball extends Shape {
...
}
• Java only supports “public” inheritance
Implicit versus explicit parameters
• Methods define their “explicit” parameters
public void bounce(int numOfBounces)
– numOfBounces is the implicit parameter
• When a method is called on an object ... the object is passed as an
“implicit” parameter
Ball b = new Ball();
b.bounce(5);
// like calling bounce(b, 5)
• Use the this keyword to access the implicit object parameter ...
public void bounce(int numOfBounces) {
for(int i = 0; i < numbOfBounces; i++)
this.bounce();
}
S. Bowers
6 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Inheritance and Constructors
Constructors are not inherited
• Must define needed constructors for each class
public class Shape {
private String name;
public Shape(String name) {
this.name = name;
}
}
// older convention
public class Ball extends Shape {
public Ball(String theName) {
name = theName;
}
}
Q: What is wrong with the above?
– name is private in Shape
– Instead, call the superclass constructor ...
public class Ball extends Shape {
public Ball(String theName) {
super(theName);
}
}
• super must be the first statement in the constructor
S. Bowers
7 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Casting Objects
Sometimes we need to cast objects to other types
Shape s = new Ball();
Ball b = (Ball)s;
Block d = (Block)a;
// should this work?
// should this work?
• We are circumventing the type system when we cast
• So you have to be very careful!
The Java Cosmic Superclass
All class (implicitly) extend the Object class
• So if we have:
public class Shape {
...
}
• We really have:
public class Shape extends Object {
...
}
• this means ... we always have a common superclass!
Object obj1 = new Ball();
Object obj2 = new Block();
S. Bowers
8 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Object[] anArray = new Object[2] {obj1, obj2};
for(Object obj : anArray)
...
The Object class defines many useful methods
• public String toString()
– returns a string representation of the object
– Called whenever object is cast to a String ...
– Including: "" + obj and System.out.println(obj)
• public boolean equals(Object obj)
– checks equality
public boolean equals(Object obj) {
if(!(obj instanceof Ball))
return false;
Ball that = (Ball)obj;
... check this the same as that ...
}
• public Object clone()
– Creates a copy
S. Bowers
9 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Method Overriding in Java
Q: What is method overriding?
• redefine/tailor a base class method in a derived class
• derived class method must have the same signature as base class
Q: What is overloading? How does it differ?
public class Ball {
...
public void hitWith(Bat theBat) {
move(theBat.getVelocity());
}
}
public class Baseball extends Ball {
...
public void hitWith(Bat theBat) {
if(!(theBat instanceof BaseballBat))
return;
else
hitWith(theBat);
// tries to call super’s hitWith
}
}
Q: Is there a problem here?
– We’re calling the same method!!!
• Instead, we can use the super keyword
S. Bowers
10 of 13
Lecture Notes
CPSC 326 (Fall 2011)
public class Baseball extends Ball {
...
public void hitWith(Bat theBat) {
if(!(theBat instanceof BaseballBat))
return;
else
super.hitWith(theBat);
}
}
Dynamic Binding in Java
• When we do this:
Ball b = new Baseball();
b.hitWith(new BaseballBat());
Q: What should happen?
– The object’s version of the method should be called
– Not the more generic version in Ball
• This is called “dynamic” binding
– Methods are bound at runtime (as opposed to compile time)
– Java mostly uses dynamic binding
– In C++, we have to use the virtual keyword
S. Bowers
11 of 13
Lecture Notes
CPSC 326 (Fall 2011)
Java Interfaces
In Java, a class can subclass (extend) at most one other class
• Different than C++, which allows “multiple” inheritance
Java provides interfaces as a workaround
• An interface is like a fully abstract class
• None of the methods are implemented
• Every class implementing an interface must implement all the methods
• Or else be declared as an abstract class
public interface Shape {
public static final int MAX_SIZE = 109;
public void move();
public Color getColor();
...
}
public interface RoundThing {
public double getRadius();
}
public class Ball implements Shape, RoundThing {
public void move() {
...
}
public Color getColor() {
...
}
S. Bowers
12 of 13
Lecture Notes
CPSC 326 (Fall 2011)
public double getRadius() {
...
}
...
}
• Technically, all methods in a public interface are public
• But good practice to put public anyway
• Interfaces can be used as types!
Shape s = new Ball();
s.move();
Q: Why would we want to do this?
– Allows us to decouple our code from any particular implementation
S. Bowers
13 of 13