Вот фрагмент кода из первой книги шаблонов головы:
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 инициализирует объект InputStream super(in)
а позже, похоже, использует этот объект, используя super.read()
.
Я немного смущен тем, как работает суперфункция. В примере Mocha очень ясно, что он обертывает внутри себя объект напитка и вызывает его методы и изменяет результаты, тогда как в классе LowerCaseInputStream он не имеет прямого отношения к изменению поведения.
В первом случае super
ссылается на конструктор в базовом классе FilterInputStream
. Если конструктор родительского класса имеет аргумент, любой класс, который его расширяет, должен явно вызвать соответствующий конструктор, используя super
. Если базовый класс просто имеет конструктор без аргументов, super
предоставляется неявным образом Java.
Во втором случае метод read
FilterInputStream
был перегружен с помощью LowerCaseInputStream
. Это означает, что любой вызов LowerCaseInputStream.read()
перейдет к его реализации. Поэтому для LowerCaseInputStream
вызывать реализацию read
в FilterInputStream
(чтобы получить стандартное поведение) он должен ссылаться на super
иначе это будет бесконечный цикл.
super
нет. Текст может быть неверно истолкован, но по-прежнему корректен по своему значению: LowerCaseInputStream.read()
будет означать метод экземпляра read()
реализованный классом LowerCaseInputStream
. Является ли класс абстрактным или нет, также не имеет значения, если есть супер реализация.
Ключевое слово super
существует, чтобы дать дочерним классам доступ к родительским классам и их открытым публичным членам. Что, как говорится:
super(in)
: вызывает конструктор суперкласса, передавая его в качестве аргумента
super.read()
: super.read()
метод read
суперкласса
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'
}
}
super.print()
не совсем понятен и осмыслен, так как в этом случае вам не понадобится ключевое слово super, поэтому некоторые могут запутаться.
super
keyword означает parent, в этом случае FilterInputStream
//this invoke parent constructor like 'FilterInputStream(in)'
super(in);
//this invoke parent read() method
super.read();
Сначала изучите базовое Java-программирование и наслаждайтесь им.