Slide navigation: Forward with space bar, → arrow key, or PgDn. Backwards with ← or PgUp.
Employee
class is a superclass.extends
keyword:
public class Manager extends Employee { added methods and fields }
public class Manager extends Employee { private double bonus; . . . public void setBonus(double bonus) { this.bonus = bonus; } }
Manager
inherits methods from superclass: getName
, getHireday
, getSalary
, raiseSalary
name
, salary
are present in all Manager
objects.public class Manager extends Employee { . . . public double getSalary() { return salary + bonus; // won't work } }
public double getSalary() { return getSalary() + bonus; // still won't work }
super
to avoid recursive call:
public double getSalary() { return super.getSalary() + bonus; }
public Manager(String name, double salary, int year, int month, int day) { super(name, salary, year, month, day); bonus = 0; }
super
must be the first statement.staff[0] = boss; staff[1] = new Employee("Harry Hacker", 50000, 1989, 10, 1); staff[2] = new Employee("Tony Tester", 40000, 1990, 3, 15);
for (Employee e : staff) System.out.println(e.getName() + " " + e.getSalary());
getName
method gets called?
Employee.getName
getSalary
method gets called?
Employee.getSalary
or Manager.getSalary
?e
!x
is declared to be of type C
. Consider a method call:
x.f(args)
f
in C
and its superclasses.private
, static
, or final
, then the compiler knows exactly which method to call (static binding).class Employee { public void setBoss(Employee boss) { ... } ... } class Manager { public void setBoss(Manager boss) { ... } // Error—unrelated method ... }
@Override
annotation to make the compiler check:
@Override public void setBoss(Employee boss)
class Employee { public Employee getBoss() { ... } ... } class Manager { public Manager getBoss() { ... } // Ok ... }
final
class cannot be extended:
public final class Executive extends Manager { . . . }
final
method cannot be overridden:
public class Employee { . . . public final String getName() { return name; } }
staff[0]
is a Manager
.Manager
methods, you need to cast:
Manager boss = (Manager) staff[0]; boss.setBonus(...);
staff[0]
wasn't actually a Manager
, a ClassCastException
occurs.instanceOf
operator:
if (staff[1] instanceof Manager) { boss = (Manager) staff[1]; . . . }
String c = (String) staff[1]; // Compile-time error
Employee
and Student
with common superclass Person
.getDescription
method, returning a description string:
an employee with a salary of $50,000.00 a student majoring in computer science
Person
?abstract
and don't provide implementation:
public abstract String getDescription();
abstract
:
public abstract class Person
public abstract class Person { private String name; public Person(String n) { name = n; } public String getName() { return name; } ... }
Person p1 = new Person("Vince Vu"); // Error! Person p2 = new Student("Vince Vu", "Economics"); // Ok
protected
field or method is accessible from subclasses:
public class Employee { protected double salary; }
Manager
method can access the salary
field.Manager
instances.Object
class and its methodsObject
is superclass of all Java classes.int
, double
, etc. are not objects.Object
:
Object obj1 = new Employee(...); Object obj2 = new int[10];
Object
class has useful methods: equals
, hashCode
, toString
equals
MethodObject.equals
tests whether the object references are identical.public boolean equals(Object otherObject) { if (this == otherObject) return true; if (otherObject == null) return false; if (getClass() != otherObject.getClass()) return false; Employee other = (Employee) otherObject; return name.equals(other.name) && salary == other.salary && hireDay.equals(other.hireDay); }
Objects.equals
method is null safe:
return Objects.equals(name, other.name) && salary == other.salary && Object.equals(hireDay, other.hireDay);
equals
Method in a Subclasssuper.equals
, then compare subclass fields:
public class Manager extends Employee { . . . public boolean equals(Object otherObject) { if (!super.equals(otherObject)) return false; Manager other = (Manager) otherObject; return bonus == other.bonus; } }
Employee
ever equal a Manager
?equals
method needs to be:
x.equals(x)
x.equals(y)
, then y.equals(x)
x.equals(y)
and y.equals(z)
, then x.equals(z)
m
is a Manager
, then m.equals(e)
and e.equals(m)
must be the same.equals
must be fixed in the superclass:
public class Person { public final boolean equals(Object otherObject) { if (this == otherObject) return true; if (otherObject == null) return false; if (!(otherObject instanceOf Person)) return false; Person other = (Person) otherObject; return id == other.id; } }
hashCode
Methodx
and y
are not equal, then x.hashCode()
and y.hashCode()
should be different.
String
class: int hash = 0; for (int i = 0; i < length(); i++) hash = 31 * hash + charAt(i);
"Hello".hashCode()
is 69609650, "Harry".hashCode()
is 69496448.x
and y
are equal, then their hash codes must be equal.
Object.hashCode
is derived from memory location.hashCode
whenever you override equals
!equals
method compares:
public class Employee { . . . public int hashCode() { return Objects.hash(name, salary, hireDay); } }
toString
MethodtoString
method is invoked on the object:
"Center: " + p // Calls p.toString()
Object.toString
yields class name and hash code.java.awt.Point[x=10,y=20]
public class Point { . . . public String toString() { return "java.awt.Point[x=" + x + ",y=" + y + "]"; } }
toString
MethodEmployee
class:
public String toString() { return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]"; }
Manager
subclass:
public String toString() { return super.toString() + "[bonus=" + bonus + "]"; }
Manager[name=...,salary=...,hireDay=...][bonus=...]
ArrayList
class manages an Object[]
array that grows and shrinks on demand.ArrayList<Employee>
to specify element type.ArrayList<Employee> staff = new ArrayList<>();
add
method to add object to the end:
staff.add(new Employee("Harry Hacker", . . .));
staff.size()
yields the current size.get
and set
methods:
Employee e = staff.get(i); staff.set(i, tony);
for (Employee e : staff) System.out.println(e);
ArrayList
can only hold objects, not int
values.Integer
wrapper class wraps an int
value.int
and Integer
is automatic:
ArrayList<Integer> list = new ArrayList<>(); list.add(3); // same as list.add(Integer.valueOf(3)); int n = list.get(i); // same as int n = list.get(i).intValue();
Integer n = 1000; n++;
==
doesn't work with wrappers.
Integer a = n + 1; Integer b = n + 1; System.out.println(a == b); // May be false
null
.
Integer n = null; System.out.println(n + 1); // Null pointer exception
System.out.printf("%d", n); System.out.printf("%d %s", n, "widgets");
public class PrintStream { . . . public PrintStream printf(String fmt, Object... args) { . . . } }
Object[]
array of the arguments.public static double max(double... values) { double largest = Double.NEGATIVE_INFINITY; for (double v : values) if (v > largest) largest = v; return largest; }
double m = max(3.1, 40.4, -5);
public enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };
public enum Size { SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL"); private String abbreviation; private Size(String abbreviation) { this.abbreviation = abbreviation; } public String getAbbreviation() { return abbreviation; } }
Enum
and inherit methods:
toString
—yields the name "SMALL"
, "MEDIUM"
, ...ordinal
—yields the position 0, 1, ...Enum.valueOf(Size.class, "SMALL")
yields Size.SMALL
Size.values()
yields all values in an array of type Size[]
Class
Class Class
object:
Object obj = ...; Class cl = obj.getClass();
System.out.println(cl.getName());
System.out.println(Arrays.toString(cl.getMethods()));
newInstance
yields an instance constructed with the no-arg constructor:
Object newObj = cl.newInstance();
Class
InstancesClass
instance from a string:
String className = ... // e.g., "java.util.Random"; Class cl = Class.forName(className);
Class cl1 = Random.class; // if you import java.util.*; Class cl2 = int.class; Class cl3 = Double[].class;
Class
describes a type which need not be a class.Class
instances are unique:
if (obj.getClass() == Employee.class) // Ok
forName
and newInstance
can throw exceptions.throws
statement.try/catch
block:
try { statements that might throw exceptions } catch (Exception e) { handler action }
forName
and newInstance
.getDeclaredFields
method yields an array of Field
objects.getDeclaredField
method yields a Field
object for a given field name.Employee harry = new Employee("Harry Hacker", 35000, 10, 1, 1989); Class cl = harry.getClass(); Field f = cl.getDeclaredField("name"); Object v = f.get(harry); f.set(harry, "Wimpy Whiner");
name
is a private field. Make this call first:
f.setAccessible(true);
toString
method in sample code.Array
class lets you create and analyze arrays dynamically.copyOf
method:
Employee[] a = new Employee[100]; . . . // array is full a = Arrays.copyOf(a, 2 * a.length);
public static Object[] badCopyOf(Object[] a, int newLength) // not useful { Object[] newArray = new Object[newLength]; System.arraycopy(a, 0, newArray, 0, Math.min(a.length, newLength)); return newArray; }
Object[]
array.public static Object goodCopyOf(Object a, int newLength) { Class cl = a.getClass(); if (!cl.isArray()) return null; Class componentType = cl.getComponentType(); int length = Array.getLength(a); Object newArray = Array.newInstance(componentType, newLength); System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength)); return newArray; }
int[] a = { 1, 2, 3, 4, 5 }; a = (int[]) goodCopyOf(a, 10);
Object
, not Object[]
getMethods
method yields an array of Method
objects.getMethod
method yields a Method
object:
Method m1 = Employee.class.getMethod("getName"); Method m2 = Employee.class.getMethod("raiseSalary", double.class);
invoke
method lets you call a method:
String n = (String) m1.invoke(harry); double s = (Double) m2.invoke(harry);
Class.newInstance
is now deprecated.class Fred { public Fred() throws IOException { throw new IOException("No Fred.properties"); } }
Fred
without throwing any checked exception:
public Fred haveFred() { try { return Fred.class.newInstance(); } catch (ReflectiveOperationException ex) { System.out.println("Caught ROE"); return null; } }
IOException
.Fred.class.getDeclaredConstructor().newInstance()which throws a checked
InvocationTargetException
.toString
on arrays.
String.class.getConstructors() [Ljava.lang.reflect.Constructor;@706a04ae
String.class.getConstructors() $17 ==> Constructor[15] { public java.lang.String(byte[]), public java.lang.String(byte[],int,int), public java.lang.String(byte[],java.nio.charset.Charset), ...}
Arrays.toString(...)
public class Contractor extends Employee { private double hourlyWage; // ??? . . . }
class Holiday extends GregorianCalendar { . . . } // ??? . . . Holiday christmas; christmas.add(Calendar.DAY_OF_MONTH, 12);
Holiday
add method?x
is a GregorianCalendar
or Holiday
object:
int d1 = x.get(Calendar.DAY_OF_MONTH); x.add(Calendar.DAY_OF_MONTH, 1); int d2 = x.get(Calendar.DAY_OF_MONTH); System.out.println(d2 - d1);
if (x is of type 1) action1(x); else if (x is of type 2) action2(x); |
⇒ | x.action(); |