interface
interface
public interface Challenge { public int getXP(); }
public class Treasure implements Challenge { ... } public class Monster implements Challenge, Destructable, ... { ... }
Compiler will force each of these classes to implement a public int getXP()
method.
Challenge first = new Monster(); Challenge reward = new Treasure();
ArrayList<Challenge> done = ArrayList<Challenge>(); done.add(first); done.add(reward); done.add(new Monster()); ... int score = 0; for (Challenge c : done) { score += c.getXP(); }
public interface Comparable<T> { public int compareTo(T obj); }
public class Circle implements Comparable<Circle> { private int radius; public Circle(int radius) { this.radius = radius; } public int compareTo(Circle c) { //sort by increasing size if (this.radius < c.radius) { return -1; }else if (this.radius > c.radius) { return 1; }else { return 0; } } //... public String toString() { return "Circle(" + this.radius + ")"; } }
Could have implemented this compareTo method in one line:
return this.radius - c.radius;
Circle big = new Circle(50); Circle mid = new Circle(20); Circle small = new Circle(5); if (small.compareTo(big) < 0) { System.out.println("Small circle comes before big circle"); } if (mid.compareTo(big) == 0) { System.out.println("mid and big are the same size"); } Circle[] circles = {mid, small, big}; java.util.Arrays.sort(circles); System.out.println(java.util.Arrays.toString(circles)); //prints: [Circle(5), Circle(20), Circle(50)]
public interface Collection<E> { public void add(E item); public E get(); public E remove(); public int size(); }
public class Stack<E> implements Collection<E> { //...existing Stack implementation here... public void add(E item) { this.push(item); } public E get() { return this.peek(); } public E remove() { return this.pop(); } //size method already exists }
Collection<String> c = new Stack<String>(); Collection<String> other = new Queue<String>(): c.add("Alice"); c.add("Bob"); c.remove(); System.out.println(c.get()); System.out.println(c.size()); //NO: c.push("Carol") //NO: c.peek()
extend
another
public class Animal { public void speak() { System.out.println("The animal vocalizes."); } } public class Dog extends Animal { public void speak() { System.out.println("Woof! Woof!"); } public void fetch(Ball b) { //???? } } public class SmallDog extends Dog { public void speak() { System.out.println("Yip! Yip! Yip!"); } } public class Cat extends Animal { public void speak() { System.out.println("Meow."); } } public class Fish extends Animal { } public class Ball { }
Class hierarchy: super/parent class vs sub/child class relationship
Animal a = new Animal(); Dog dog = new Dog(); SmallDog pom = new SmallDog(); Cat cat = new Cat(); Fish fish = new Fish();
speak()
?
fetch
?
Basically, starts at most specific class and works up until it finds a definition to execute.
Animal beast = new Fish(); beast.speak(); //prints? Dog dog = new SmallDog(); dog.speak(); //prints? Animal[] zoo = {new Dog(), new SmallDog(), new Cat(), new Fish()}; for (Animal a : zoo) { a.speak(); } Animal rex = new Dog(); //NO: rex.fetch(new Ball());
double three = 3; double four = 4.0; int two = (int) (four / 2.0);
Animal beast = new Dog(); Dog rover = (Dog) beast; SmallDog rex = (SmallDog) beast; //NO: causes ClassCastException
instanceof
operator
if (beast instanceof Dog) { Dog rex = (Dog) beast; //safe, because I checked first rex.fetch(new Ball()); }
Object
Object
Dog dog = new Dog(); String str = "Hello, " + dog; //calls toString() System.out.println(dog); //calls toString()
Dog canine = null; String str = "Hello, " + canine; System.out.println(canine); //canine.toString() would crash with NPE here
Dog@6629a046
//assuming earlier Circle definition
Circle one = new Circle(10); Circle two = new Circle(10); Circle tu = two; System.out.println(one == two); //false System.out.println(tu == two); //true System.out.println(one.equals(two)); //false System.out.println(tu.equals(two)); //true
public class Circle implements Comparable<Circle> { //... earlier definition... public boolean equals(Object obj) { //note the Object if (obj instanceof Circle) { //also catches null Circle circle = (Circle) obj; return this.radius == circle.radius; } return false; } }
Circle one = new Circle(10); Circle two = new Circle(10); Circle tu = two; System.out.println(one.equals(two)); //true System.out.println(tu.equals(two)); //true
public String toSting() { //... }
public boolean equals(Circle e) { //... }
@Override public String toString() { //... }
@Override public boolean equals(Circle e) { //... }
super
keyword: Methodspublic class SmallDog extends Dog { public void speak() { super.speak(); System.out.println("Yip! Yip! Yip!"); } }
super
is like this
, but refers to immediate superclass.
super
keyword: Constructorspublic class Rectangle { private int width; private int height; public Rectangle(int width, int height) { this.width = width; this.height = height; } //... }
public class Square extends Rectangle { public Square(int side) { super(side, side); //actually required } }
protected
protected
:
public class Rectangle { protected int width; protected int height; public Rectangle(int width, int height) { this.width = width; this.height = height; } //... }
this.width
or this.height
as if defined them itself
public abstract class Animal { public void locomote() { //..implementation here... } public void respire() { //...implementation here... } public abstract void speak(); }
new Animal()
;