1 of 35

Lecture 17 - CS 159 Specialization

Prof. Alvin Chao

Due this week:

  • Mon 11pm Reading Chp 10-11
  • Lab 13 Specialization

After break PA1 Mon Oct 21- 11pm

Take poll at: pollEV.com/chaoaj

2 of 35

  • What is the relationship between "dogs" and "animals"?

  • A dog is an animal�
  • All dogs are animals but not all animals are dogs

  • The set dogs is a true subset of the set animals

animals

dogs

3 of 35

  • What is the relationship between "dogs" and "animals"?

  • What is a class?
    • A definition of a set that is written in terms of the properties of the elements (i.e., an intensive definition of a set)
    • The set of elements so defined
  • What is an object?
    • An element of the set

class

object

4 of 35

Sub and Super Sets

  • A Subset:
    • Has additional characteristics
    • Is a specialization
    • Mathematical Notation: A⊂B denotes that A is a (proper) subset of B
  • A Superset:
    • Ignores some characteristics
    • Is a generalization
    • Mathematical Notation: G⊃H denotes that G is a (proper) superset of H

5 of 35

Specialization / Generalization of a class

    • The "is-a" relationship:
      1. An object of class A "is-an" object of class B if A is/does everything that B is/does and more
    • Other Terminology:
      • Subclass/Superclass
      • Child Class/Parent Class
      • Derived Class/Base Class

6 of 35

Specialization of enums

    • Recall:
      • A definition of a set that is written by listing the elements (i.e., an extensive definition of a set)
    • What Would a Specialization Be?
      • A subset (i.e., a list of elements to omit from the parent)
    • The Implication:
      • Java does not allow enums to be specialized (though the "is a" relationship can be achieved in other ways as discussed later)

7 of 35

Inheritance

  • A Loose Definition:
    • Instances of the child class have the characteristics of the parent class without having to implement them
  • What Is/Isn't Inherited in Java?
    • The subclass inherits the attributes of the superclass
    • The subclass inherits the methods of the superclass
    • The subclass does not inherit constructors from the superclass
  • Visibility/Accessibility:
    • The subclass cannot directly access private members in the superclass
    • The superclass can restrict access to descendants by declaring members to be protected

8 of 35

Inheritance

  • Visibility:
    • Protected accessibility/visibility is denoted using a #
  • Inherited Methods:
    • Inherited methods are (typically) not explicitly listed in the subclass

9 of 35

Example - Class Hierarchies

10 of 35

Java Specialization Syntax

  • Declaring a Subclass:
    • Use extends in the declaration of the class
  • Accessing Members in a Superclass from a Subclass:
    • Use super as the left-side operand of the . operator to eliminate ambiguity (if needed)
  • Calling the Constructor in a Superclass from a Subclass:
    • Call super() (which must be the first statement in a constructor of the subclass)

11 of 35

Specialization + Constructors in Java

  • Explicit Value Constructors in the Subclass:
    • Should include a call to an appropriate constructor in the superclass
    • If no version of super() is called explicitly, the default constructor in the superclass will be called (so, if there isn't one, the subclass won't compile)
  • Default Constructors in the Subclass:
    • Should include a call to the default constructor in the superclass
    • If no version of super() is called explicitly, the default constructor in the superclass will be called (so, if there isn't one, the subclass won't compile)

12 of 35

Common uses of Specialization

  • Purpose:
    • Add attributes
    • Add behaviors
    • Modify existing behavior
  • Situations:
    • You only have the byte code (i.e., the .class file) for an existing class
    • You have the source code (i.e., the .java file) for an existing class but don't want to change it
    • You are designing classes "from scratch"

13 of 35

Adding Characteristics to an Existing Class

Existing Classes:

  • Part of the Java API (e.g., DecimalFormat)
  • Written by a "third party"
  • If only:
    1. it also had the following attributes
    2. it also had the following methods

14 of 35

Example - FieldFormat

  • import java.text.*;
  • public class FieldFormat extends DecimalFormat
  • {
  • private int fieldWidth = -1;
  • public FieldFormat()
  • {
  • super();
  • }
  • public String fitStringToField(String original)
  • {
  • int i;
  • String returnString;
  • returnString = "";
  • if (fieldWidth > 0) // The field width has been set
  • {
  • if (original.length() <= fieldWidth) // Lengthen original
  • {
  • for (i=1; i <= fieldWidth-original.length(); i++)
  • {
  • returnString += " ";
  • }
  • returnString += original;
  • }
  • else // Shorten original
  • {
  • returnString = original.substring(0, fieldWidth);
  • }
  • }
  • else // The field width hasn't been set
  • {
  • returnString = original;
  • }
  • return returnString;
  • }
  • public void setFieldWidth(int width)
  • {
  • fieldWidth = width;
  • }
  • }

15 of 35

Do these compile?

Examples in visualizer

16 of 35

Modifying behavior of an existing class

Existing Classes:

  • Part of the Java API (e.g., StringTokenizer)�Written by a "third party"
  • If only:
    • it did this instead
  • What Can the Subclass Do?
    • Override methods in the superclass (i.e., include a method with the same signature but a different implementation)
  • Example in visualizer

17 of 35

Will these compile?

18 of 35

Adding / Modifying Characteristics from Scratch

  • Situation:
    • You are implementing all of the classes
    • You have the source code
  • Why Use Specialization?
    • The base class has already been thoroughly tested
    • The derived class adds significant complexity that is not required by all objects

19 of 35

Adding / Modifying Characteristics from Scratch

  • public class EmergencyMessage
  • {
  • private String message;
  • public EmergencyMessage(String message)
  • {
  • this.message = message;
  • }
  • public String getMessage()
  • {
  • return message;
  • }
  • }

20 of 35

Adding / Modifying Characteristics from Scratch

  • public class Alert extends EmergencyMessage
  • {
  • private String supplement;
  • public Alert(String message, String supplement)
  • {
  • super(message);
  • this.supplement = supplement;
  • }
  • public String getSupplement()
  • {
  • return supplement;
  • }
  • }

21 of 35

Another example: Chirp.java

  • import java.util.*;
  • public class Chirp

{

  • private String delimiters; // Delimiters between words
  • private String text; // The text of the message
  • public Chirp(String typed)
  • {
  • text = typed;
  • delimiters = " ,.;!?-\n\r";
  • }
  • public int getNumberOfWords()
  • {
  • int numberOfWords;
  • StringTokenizer tokenizer;
  • tokenizer = new StringTokenizer(text, delimiters);
  • numberOfWords = tokenizer.countTokens();
  • return numberOfWords;
  • }
  • public String getDelimiters()
  • {
  • return delimiters;
  • }
  • public String getText()
  • {
  • return text;
  • }
  • }

22 of 35

An Expansion

  • import java.io.*;
  • import java.util.*;
  • public class ExpandedChirp extends Chirp{
  • private Properties abbreviations;
  • public ExpandedChirp(String typed){
  • super(typed);
  • InputStream is;
  • abbreviations = new Properties();
  • try{
  • is = new FileInputStream("abbreviations.txt");
  • abbreviations.load(is);
  • }
  • catch (IOException ioe){
  • // There was a problem opening the file
  • // containing the abbreviations
  • }
  • }
  • public String getText(){
  • String tempText;
  • // Use getText() in the parent
  • tempText = replaceAbbreviations(super.getText());
  • return tempText;
  • }
  • private String replaceAbbreviations(String msg){
  • String replaced, token, word;
  • StringTokenizer tokenizer;
  • replaced = "";
  • tokenizer = new StringTokenizer(msg, getDelimiters(), true);
  • while (tokenizer.hasMoreTokens())
  • {
  • token = tokenizer.nextToken();
  • word = abbreviations.getProperty(token);
  • if (word == null) replaced += token;
  • else replaced += word;
  • }
  • return replaced;
  • }
  • }

23 of 35

The driver

  • public class ChirpDriver
  • {
  • public static void main(String[] args)
  • {
  • if ((args.length > 0) && (args[0].equals("-old")))
  • {
  • ExpandedChirp chirp;
  • chirp = new ExpandedChirp("This is it. TTFN!");
  • System.out.println(chirp.getText());
  • }
  • else
  • {
  • Chirp chirp;
  • chirp = new Chirp("This is it. TTFN!");
  • System.out.println(chirp.getText());
  • }
  • }
  • }

24 of 35

Shadowing

  • An Observation:
    • It is possible to have an attribute in the derived class with the same type and name as an attribute in the base class (which is called shadowing)
  • Best Practice:
    • Where possible, shadowing should be avoided because it is confusing
  • Shadowing Private Attributes:
    • You may not always know the private attributes in the base class (especially if you don't have the source code for the base class)

25 of 35

Conventions when overriding

  • UML:
    • Overridden methods are (typically) explicitly listed in the subclass
  • Java:
    • Overridden methods are often annotated with @Override

26 of 35

A common mistake

  • The Situation:
    • A method in the derived class needs to call the method it overrides in the base class
  • The Mistake:
    • Forgetting to use super.
  • The Symptom:
    • A stack overflow (i.e., the method in the derived class calls itself until it runs out of memory)

27 of 35

Another mistake

  • The Situation:
    • An assignment statement doesn't compile (and you think it should or, at least, really want it to)
  • A "Rookie" Mistake:
    • Use a typecast
  • Why This Makes the Compiler Happy:
    • The compiler believes the programmer

28 of 35

Example

  • Chirp c;
  • ExpandedChirp e;
  • c = new Chirp("TTFN");
  • e = (ExpandedChirp)c;
  • Why won't the last line compile without the type cast?
    1. A Chirp is not an Expanded Chirp and methods might be called on e that it doesn't have
  • Why will the last line compile as is?
    • The compiler believes the programmer
  • What will happen at run-time?
    • A ClassCastException will be thrown

29 of 35

Static Members

  • In a Base Class:
    • Are attributes/methods of both the base class and any derived classes
  • When This Can Be Confusing:
    • When you have multiple derived classes specialize the same base class (because they will "share" the same static members)

30 of 35

Preventing Specialization in Java

  • A Particular Method:
    • A method that is declared to be final can't be overridden by a subclass
  • An Entire Class:
    • A class that is declared to be final can't be specialized (i.e., a class that extends a final class will not compile)

31 of 35

Preventing Specialization in UML

  • A Particular Method:
    • A common convention is to include {leaf} after the return type
  • An Entire Class:
    • A common convention is to include {leaf} after the name

32 of 35

Oddities of Specialization in Java

  • The Object Class:
    • All classes that don't explicitly extend a class implicitly extend the Object class
  • Implication:
    • All objects have clone(), equals() and toString() methods, though they don't always do what you want

33 of 35

A Java detail we skipped before

  • Recall:
    • Some exceptions are checked and some are unchecked
  • How To Distinguish:
    • Unchecked Exceptions - Descendants of RuntimeException�Checked Exceptions - All other descendants of Exception�

34 of 35

Things we’ve danced around

  • Recall:
    • In JUnit, assertEquals() works with int values, double values, objects, etc...
    • The printf() method in the PrintWriter class is passed a format string and then a variable number of arguments of any type
  • How?
    • assertEquals() is overloaded and one of the versions has Object parameters
    • The parameters of printf() are String and Object...

35 of 35

Lab