Worksheet: J3 | CS 2113 Software Engineering - Fall 2023

Worksheet: J3

Worksheets are self-guided activities that reinforce lectures. They are not graded for accuracy, only for completion. Worksheets are due by Sunday night before the next lecture.

Create a new repo using all the steps in Lab 0 called yourgitusername-worksheet-J3. Submit a file called worksheet-J3.md in your repo for this assignment.

Note

Attempt to answer these questions before running the code. This will improve your ability to analyze and reason about code without an IDE or compiler. This skill we be helpful on the exams.

Questions

  1. Define polymorphism in the context of Java and provide one example where it is valuable?

    Reveal Solution

  2. Consider the following program from the class notes

    public class Ex3 {
      public static void main(String[] args) {
        Random   rand = new Random(System.currentTimeMillis());
        Point    v    = new Point(3, 4);
        LabPoint w    = new LabPoint(5, 2, "A");
        String   x    = "I'm a string";
        Scanner  y    = new Scanner(System.in);
    
        Object u;
        int i = rand.nextInt(4);
    
        if( i == 0 )
          u = v;
        else if( i == 1 )
          u = w;
        else if( i == 2 )
          u = x;
        else
          u = y;
        System.out.println(u); //<--
      }
    }
    

    Explain how polymorphism makes this program possible.

    Reveal Solution

  3. What is the output of this program? You should be able to do this without running the program!

    class A {
        public String toString(){
            return "A";
        }
    }
    
    class B extends A{
        public String toString() {
            return "B";
        }
    }
    
    class C extends A {
        public String toString() {
            return super.toString();
        }
    }
    
    class D extends C {
        public String toString() {
            return super.toString();
        }
    }
    
    public class tmp {
        public static void main(final String args[]) {
            D d = new D();
            System.out.println(d.toString());
        }
    }
    

    Reveal Solution

  4. What is the output of this program? You should be able to do this without running the program!

    class A {
        public String toString() {
            return "A";
        }
        
        public String fancyToString() {
            return "~~A~~";
        }
    }
    
    class B extends A {
        public String toString() {
            A letterA = this;
            return letterA.fancyToString();
        }
        public String fancyToString() {
            return "~~B~~";
        }
    }
    
    public class LetterPrinter {
        public static void main(final String args[]) {
            B letterB = new B();
            System.out.print(letterB.toString() + " ");
            
            A letterA = letterB;
            System.out.println(letterA.toString());
        }
    }
    

    Reveal Solution

  5. What is the output of this program? You should be able to do this without running the program!

    class A {
        public String toString() {
            return "A";
        }
        
        public String fancyToString() {
            return "~~A~~";
        }
    }
    
    class B extends A {
        public String fancyToString(){
            return "~~B~~";
        }
    }
    
    public class LetterPrinter {
        public static void main(final String args[]) {
            B letterB = new B();
            System.out.print(letterB.toString() + " ");
            
            A letterA = letterB;
            System.out.println(letterA.toString());
        }
    }
    

    Reveal Solution

  6. Consider the first two class declarations. What is the output of compiling the program below?

    abstract class Letter {
        protected boolean uppercase;
    
        abstract String get_name();
    
        abstract int get_alphabet_position();
    }
    
    class A extends Letter {
        public String toString() {
            return "A";
        }
    
        protected int get_alphabet_position() {
            return 1;
        }
    
        private String get_name() {
            return "A";
        }
    }
    

    Reveal Solution

  7. If we change the implementation of A to the following, what does the code below output?

    abstract class Letter {
        protected boolean uppercase;
    
        abstract String get_name();
    
        abstract int get_alphabet_position();
    }
    
    class A extends Letter {
        public String toString() {
            return "A";
        }
    
        public int get_alphabet_position() {
            return 1;
        }
    
        protected String get_name() {
            return "A";
        }
    }
    
    public class Main {
        public static void main(final String args[]) {
            A a = new A();
            System.out.println("A: " + a.get_alphabet_position());
        }
    }
    
    

    Reveal Solution

  8. What is the output of this program? You should do this without running the program.

    class A {
        public String toString() {
            return "A";
        }
    }
    
    class B extends A {
        public String toString() {
            return "B";
        }
    }
    
    public class PolymorphicOverload {
        public void foo(B letterB1, B letterB2) {
            // 2
            System.out.println("foo2: " + letterB1 + " " + letterB2);
        }
    
        public void foo(A letterA1, A letterA2) {
            // 1
            System.out.println("foo1: " + letterA1 + " " + letterA2);
        }
        public static void main(String args[]) {
            PolymorphicOverload f = new PolymorphicOverload();
            B letterB = new B();
            A letterA = (A) new B();
            f.foo(letterB, letterA);
        }
    }
    

    Reveal Solution

  9. Assume that class A is implemented in such a way so that the program will compile and run. What is the output? You should do this problem without running the code.

    public class Temp {
        public static void foo(A a) {
            System.out.println("foo1: " + a.get_name());
        }
        public static void foo(Letter a) {
            System.out.println("foo2: " + a.get_name());
        }
        public static void main(final String args[]) {
            Letter a = (Letter) new A();
            foo(a);
        }
    }
    

    Reveal Solution

  10. Suppose you had the following class structures

    public class Species {
        String genus;
        String species;
        public Species(String g, String s) {
            genus = g;
            species = s;
        }
        
        public Species(Species s) {
            genus = s.genus;
            species = s.species;
        }
        
        public String toString() {
            return genus + " " + species;
        }
    }
    
    public class Breed extends Species {
        protected String breed;
    
        public Breed(String b, String g, String s) {
            super(g, s);
            breed = b;
        }
    
        public Breed(String b, Species s) {
            super(s);
            breed = b;
        }
    
        public String toString() {
            return super.toString() + "(" + breed + ")";
        }
    }
    
    public class Pet {
        String name;
        Species species;
    
        public Pet(String n, Species s) {
           name = n;
           species = s;
        }
    
        public String toString() {
            String ret = "Name: " + name + "\n";
            ret += "Species: " + species;
            retunr ret;
        }       
    }
    

    What is the output of the following snippet of code? If there is an ERROR, describe the error. You should not need to run the code to determine the output.

        
       Species dog = new Species("Canis","Familaris");
       Breed shorthair = new Breed("shorthair", new Species("Felis","Catus"));
       Pet fluffy = new Pet("fluffy", new Breed("pomeranian", dog));
       Pet george = new Pet("george", dog);
       Pet brutus = new Pet("brutus", (Species) shorthair);
       
       System.out.println(fluffy);
       System.out.println(george);
       System.out.println(brutus);
    

    Reveal Solution

  11. Consider the following classes

    public class A {
        public int foo() {
            return 42;
        }
    
        public int bar() {
            return foo() + 8;
        }
    }
    
    public class B extends C {
        public int foo() {
            return 41;
        }
    
        public char baz() {
            return "y";
        }
    }
    
    public class C extends A {
        public char baz() {
            return "x";
        }
    }
    
    public class D extends A {
        public int bar() {
            return 7;
        }
    }
    
    public class E extends C {
        public int bar() {
            return foo() + 20;
        }
    }
    
    

    Draw the class hierarchy for the above classes, that is the UML diagram that simply shows who inherits from whom.

    Reveal Solution

  12. Continuing with the classes from the previous question, consider a mystery function that returns a object of the given class. You do not know the definition of the mystery function, other than it compiles properly and returns an object of the class. For each of the following method calls marked below, indicate the value of the output, if the output cannot be determined, or if there is an error.

    
    A a = mysteryA(); //<-- mystery function, this line compiles (the below may not!)
    System.out.println(a.foo()); //<-- Mark A.1
    System.out.println(a.bar()); //<-- Mark A.2
    System.out.println(a.baz()); //<-- Mark A.3
    
    
    B b = mysteryB(); //<-- mystery function, this line compiles (the below may not!)
    System.out.println(b.foo()); //<-- Mark B.1
    System.out.println(b.bar()); //<-- Mark B.2
    System.out.println(b.baz()); //<-- Mark B.3
    
    D d = mysteryD(); //<-- mystery function, this line compiles (the below may not!)
    System.out.println(d.foo()); //<-- Mark D.1
    System.out.println(d.bar()); //<-- Mark D.2
    System.out.println(d.baz()); //<-- Mark D.3
    

    Reveal Solution

  13. What is the difference between a class and an abstract class?

    Reveal Solution

  14. If you were to create an abstract class for a Car – what features could be defined in the implemented class vs. what could be defined in the abstract class? Provide justifications for your design.

    Reveal Solution