1 In ToyTest.java, comment out Toy's default constructor and explain what happens.
package job;
import java.util.*;
interface HasBatteries {}
interface Waterproof {}
interface Shoots {}
class Toy {
//Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots {
FancyToy() {
super(1);
}
}
public class Main {
static void printInfo(Class cc) {
System.out.println("Class name: " + cc.getName() +
" is interface? [" + cc.isInterface() + "]");
System.out.println("Simple name: " + cc.getSimpleName());
System.out.println("Canonical name : " + cc.getCanonicalName());
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("job.FancyToy");
} catch (ClassNotFoundException e) {
System.out.println("Can't find FancyToy");
System.exit(1);
}
printInfo(c);
for (Class face : c.getInterfaces())
printInfo(face);
Class up = c.getSuperclass();
Object obj = null;
try {
// Requires default constructor:
obj = up.newInstance();
} catch (InstantiationException e) {
System.out.println("Cannot instantiate");
System.exit(1);
} catch (IllegalAccessException e) {
System.out.println("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());
}
}
output:
Class name: job.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : job.FancyToy
Class name: job.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : job.HasBatteries
Class name: job.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : job.Waterproof
Class name: job.Shoots is interface? [true]
Simple name: Shoots
Canonical name : job.Shoots
Cannot instantiate
2 Incorporate a new kind of interface into ToyTest.java andverify that it is detected and displayed properly.
package job;
import java.util.*;
interface HasBatteries {}
interface Waterproof {}
interface Shoots {}
interface A{}
class Toy {
Toy() {}
Toy(int i) {}
}
class FancyToy extends Toy implements HasBatteries, Waterproof, Shoots,A {
FancyToy() {
super(1);
}
}
public class Main {
static void printInfo(Class cc) {
System.out.println("Class name: " + cc.getName() +
" is interface? [" + cc.isInterface() + "]");
System.out.println("Simple name: " + cc.getSimpleName());
System.out.println("Canonical name : " + cc.getCanonicalName());
}
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("job.FancyToy");
} catch (ClassNotFoundException e) {
System.out.println("Can't find FancyToy");
System.exit(1);
}
printInfo(c);
for (Class face : c.getInterfaces())
printInfo(face);
Class up = c.getSuperclass();
Object obj = null;
try {
// Requires default constructor:
obj = up.newInstance();
} catch (InstantiationException e) {
System.out.println("Cannot instantiate");
System.exit(1);
} catch (IllegalAccessException e) {
System.out.println("Cannot access");
System.exit(1);
}
printInfo(obj.getClass());
}
}
output:
Class name: job.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : job.FancyToy
Class name: job.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : job.HasBatteries
Class name: job.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : job.Waterproof
Class name: job.Shoots is interface? [true]
Simple name: Shoots
Canonical name : job.Shoots
Class name: job.A is interface? [true]
Simple name: A
Canonical name : job.A
Class name: job.Toy is interface? [false]
Simple name: Toy
Canonical name : job.Toy
3 Add Rhomboid to Shapes.java. Create a Rhomboid, upcast it to a Shape, then downcast it back to a Rhomboid. Try downcasting to a Circle and see what happens.
package job;
import java.util.*;
abstract class Shape{
abstract void draw();
abstract void erase();
}
class Rhomboid extends Shape{
public void draw() { System.out.println("Rhomboid.draw()"); }
public void erase() { System.out.println("Rhomboid.erase()"); }
}
class Circle extends Shape{
public void draw() { System.out.println("Circle.draw()"); }
public void erase() { System.out.println("Circle.erase()"); }
}
public class Main {
public static void main(String[] args) {
try {
Shape a = new Rhomboid();
a.draw();
((Rhomboid) a).draw();
((Circle) a).draw();
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
output:
Rhomboid.draw()
Rhomboid.draw()
java.lang.ClassCastException: class job.Rhomboid cannot be cast to class job.Circle (job.Rhomboid and job.Circle are in unnamed module of loader 'app')
at job.Main.main(Main.java:33)
4 Modify the previous exercise so that it uses instancof to check the type before performing the downcast.
package job;
import java.util.*;
abstract class Shape{
abstract void draw();
abstract void erase();
}
class Rhomboid extends Shape{
public void draw() { System.out.println("Rhomboid.draw()"); }
public void erase() { System.out.println("Rhomboid.erase()"); }
}
class Circle extends Shape{
public void draw() { System.out.println("Circle.draw()"); }
public void erase() { System.out.println("Circle.erase()"); }
}
public class Main {
public static void main(String[] args) {
try {
Shape a = new Rhomboid();
if(a instanceof Shape) {
a.draw();
}
if(a instanceof Rhomboid) {
((Rhomboid) a).draw();
}
else if(a instanceof Circle) {
((Circle) a).draw();
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
5 Implement a rotate(Shape) method in Shapes.java, such that it checks to see if it is rotating a Circle (and, if so, doesn't perform the operation).
package job;
import java.util.*;
class Shape {
public void draw() {
}
public void erase() {
}
public void rotate() {
}
}
class Square extends Shape {
public void draw() {
System.out.println("Square.draw()");
}
public void erase() {
System.out.println("Square.erase()");
}
public void rotate() {
System.out.println("Square.rotate()");
}
}
class Triangle extends Shape {
public void draw() {
System.out.println("Triangle.draw()");
}
public void erase() {
System.out.println("Triangle.erase()");
}
public void rotate() {
System.out.println("Triangle.rotate()");
}
}
class Circle extends Shape {
public void draw() {
System.out.println("Circle.draw()");
}
public void erase() {
System.out.println("Circle.erase()");
}
public void rotate() {
System.out.println("Circle.rotate()");
}
}
class RandomShapeGenerator {
private Random rand = new Random(47);
public RandomShapeGenerator() {
}
public Shape next() {
switch (rand.nextInt(3)) {
default:
case 0:
return new Circle();
case 1:
return new Square();
case 2:
return new Triangle();
}
}
}
public class Main {
private static RandomShapeGenerator gen = new RandomShapeGenerator();
public static void main(String[] args) {
Shape[] s = new Shape[9];
// Fill up the array with shapes:
for (int i = 0; i < s.length; i++)
s[i] = gen.next();
// Make polymorphic method calls:
for (Shape shp : s) {
if (!(shp instanceof Circle)) shp.rotate();
}
}
}
output:
Radom
6 Modify Shapes.java so that it can "highlight" (set a flag in) all shapes of a particular type. The toString() method for each derived Shape should indicate whether that Shape is "highlighted."
package job;
im