1

Here is a code snippet from the head first design patterns book:

public class LowerCaseInputStream extends FilterInputStream {

    public LowerCaseInputStream(InputStream in) {
        super(in);
    }

    public int read() throws IOException {
        int c = super.read();
        return (c == -1 ? c : Character.toLowerCase((char)c));
    }

    public int read(byte[] b, int offset, int len) throws IOException {
        int result = super.read(b, offset, len);
        for (int i = offset; i < offset+result; i++) {
            b[i] = (byte)Character.toLowerCase((char)b[i]);
        }
        return result;
    }
}

There is another toy example in the same chapter:

public class Mocha extends CondimentDecorator {
    Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    public double cost() {
        return .20 + beverage.cost();
    }
}

These two are quite similar except that the Macha class has a concrete object inside that it initialize and use, while the LowerCaseInputStream class initializes an InputStream object by super(in) and later seems to make use of this object by using the super.read() function.

I am a bit confused about how the super function works here. In the Mocha example, it's very clear that it wraps a beverage object inside and calls its methods and modifies the results, while in the LowerCaseInputStream class it's not straight-forward how the behavior modification happened.

qed
  • 22,298
  • 21
  • 125
  • 196

4 Answers4

6

In the first case super refers to the constructor in the base class FilterInputStream. If the constructor of a parent class has argument, any class that extends it must explicitly call the appropriate constructor using super. If the base class simply has a no-argument constructor the super is supplied implicitly by Java.

In the second case, FilterInputStream read method has been overloaded by LowerCaseInputStream. This means that any call to LowerCaseInputStream.read() would go to its implementation. So for LowerCaseInputStream to call the read implementation in FilterInputStream (to get the standard behavior) it must reference super otherwise it would be an infinite loop.

John B
  • 32,493
  • 6
  • 77
  • 98
  • Ok, I see, an abstract class can contain static methods. – qed Jul 31 '14 at 14:03
  • 1
    @qed static methods have nothing to do with that, in fact there is no `super` for static methods. The text might be misunderstood but is still correct in its meaning: `LowerCaseInputStream.read()` would mean the instance method `read()` as implemented by class `LowerCaseInputStream`. Whether a class is abstract or not is also not relevant if there is a super implementation. – Thomas Jul 31 '14 at 14:09
  • You mean there is a `super` method implemented in FilterInputStream? – qed Jul 31 '14 at 14:12
  • No, `super` is a Java keyword that provides a reference to the base class. As I state, in the first case it references the parent class' constructor. In the second, it allows for invocation of the parent class' method (read) which has been overridden and is therefore not accessible any other way. Please read the docs in the provided links. – John B Jul 31 '14 at 14:23
2

The keyword super exists to give child classes access to their parent classes and their exposed public members. That being said:

  1. super(in): Calls the superclass's constructor, passing in the stream as an argument

  2. super.read(): Calls the superclass's read method

kolossus
  • 20,559
  • 3
  • 52
  • 104
0

super keyword means parent, in this case FilterInputStream

//this invoke parent's constructor like `FilterInputStream(in)`
super(in);

//this invoke parent's read() method
super.read();

Learn basic Java Programming first well and enjoy it.

Wundwin Born
  • 3,467
  • 19
  • 37
0

super() in this case is just a keyword that allows you to call the constructor of the superclass (hence the name). You can call other functions using super.function() too.

Example,

public class A
{
     protected String myName;

     public A(String name)
     {
         this.myName = name;
     }

     public void print(String input)
     {
         System.out.println("" + input);
     }
}

public class B extends A
{
     public B(String name)
     {
         super(name); //calls A(String name) constructor above
     }

     @Override
     public void print(String input)
     {
         if(input == null || "".equals(input))
         {
             System.out.println(this.myName);
         }
         else
         {
             super.print(input); //calls A.print(String input)
         }
     }
}

public class Main
{
     public static void main(String[] args)
     {
         B b = new B("qed");
         b.print(null); //prints 'qed'
     }
}
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • The `super.print()` example is not really clear and meaningful, since you'd not need the super keyword in that case and thus some might get confused. – Thomas Jul 31 '14 at 13:58
  • @Thomas reasonable criticism, changed it a bit and hope I made it better – EpicPandaForce Jul 31 '14 at 14:03