超级函数如何在java中工作?

时间:2014-07-31 13:51:23

标签: java oop decorator

以下是头部设计模式书中的代码片段:

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;
    }
}

同一章中还有另一个玩具示例:

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();
    }
}

这两个非常相似,只是Macha类内部有一个具体对象,它初始化和使用,而LowerCaseInputStream类通过super(in)初始化一个InputStream对象,后来似乎通过使用super.read()功能。

我对超级功能如何在这里工作有点困惑。在Mocha示例中,很明显它将一个饮料对象包装在其中并调用其方法并修改结果,而在LowerCaseInputStream类中,行为修改的发生方式并不是直截了当。

4 个答案:

答案 0 :(得分:6)

在第一种情况下,super引用基类FilterInputStream中的构造函数。如果父类的构造函数具有参数,则任何扩展它的类都必须使用super显式调用相应的构造函数。如果基类只有一个无参数构造函数,则super由Java隐式提供。

在第二种情况下,FilterInputStream read方法已被LowerCaseInputStream重载。这意味着对LowerCaseInputStream.read()的任何调用都将转到其实现。因此,LowerCaseInputStream要在read中调用FilterInputStream实现(以获取标准行为),它必须引用super,否则它将是无限循环。

答案 1 :(得分:2)

关键字super的存在是为了让子类可以访问其父类及其公开的公共成员。话虽如此:

  1. super(in):调用超类的构造函数,将流作为参数传递

  2. super.read():调用超类的read方法

答案 2 :(得分:0)

super关键字表示父级,在本例中为FilterInputStream

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

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

首先学习基本的Java编程并享受它。

答案 3 :(得分:0)

在这种情况下,

super()只是一个关键字,允许您调用超类的构造函数(因此名称)。您也可以使用super.function()调用其他函数。

实施例,

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'
     }
}