2016-07-10 2 views
-1
public class Base { 
    public Base() { 
    foo(); 
    } 

public void foo() { 
    System.out.println("Base.foo()"); 
    } 
} 



public class Derived extends Base { 

public Derived() {} 

public void foo() { 
    System.out.println("Derived.foo()"); 
    } 
} 

А потом, когда я называю те:Как заставить мой конструктор подкласса не вызывать конструктор базового класса?

public class Running { 

public static void main(String[] args) { 
    Base b = new Base(); 
    Derived d = new Derived(); 
    } 
} 

Он выводит:

*Base.foo()* 

*Derived.foo()* 

Так почему же, когда он попадает в полученный конструктор, он вызывает базовый конструктор, но использует метод производный-х вместо?

PS: Если я отмечаю эти методы как частные, он будет печатать:

*Base.foo()* 

*Base.foo()* 
+0

Пожалуйста отступа правильно и будет легче читать. Вы переопределяете метод, поэтому вызывается наиболее конкретная реализация для типа объекта. Переходите к чтению при переопределении метода в производном классе. С другой стороны, не следует избегать вызова конструктора базового класса, потому что необходимо также создать «базовую часть» объекта. В реальной жизни это также чаще всего то, что вы хотите. –

ответ

2

Это как Java работает читать эту страницу https://docs.oracle.com/javase/tutorial/java/IandI/super.html

и более конкретно примечание здесь:

Примечание. Если конструктор явно не вызывает конструктор суперкласса , компилятор Java автоматически вставляет вызов в no-arg ument конструктора суперкласса. Если у суперкласса нет конструктора без аргументов, вы получите ошибку времени компиляции. Объект имеет такой конструктор, поэтому, если Object является единственным суперклассами, проблем нет.

Таким образом, как вы можете видеть, это ожидаемое поведение. Даже если у вас есть супер-вызов, он все равно автоматически вставляет его.

В отношении второго вопроса, даже если вы находитесь в теле супер-конструктора, все еще вы являетесь экземпляром подтипа. Кроме того, если вы знакомы с C++, прочитайте это Can you write virtual functions/methods in Java?

Причина, по которой он будет писать базовый класс при маркировке с помощью private, заключается в том, что частные методы не наследуются. Это часть темы Inheritance in Java.

0

Потому что в contructor класса Derived он автоматически получает вызов super(), если вы не добавляете вызов super или другому конструктору в том же классе (используя это).

1

Чтобы ответить на вопрос в своем названии. Как я уже сказал, вы не можете избежать вызова конструктора базового класса (или одного из конструкторов базового класса, если он содержит более одного). Разумеется, вы можете легко исключить тело исполняемого конструктора. Например, как это:

public class Base { 

    public Base(boolean executeConstructorBody) { 
     if (executeConstructorBody) { 
      foo(); 
     } 
    } 

    public void foo() { 
     System.out.println("Base.foo()"); 
    } 
} 

public class Derived extends Base { 

    public Derived() { 
     super(false); 
    } 

    public void foo() { 
     System.out.println("Derived.foo()"); 
    } 
} 

public class Running { 

    public static void main(String[] args) { 
     Base b = new Base(true); 
     Derived d = new Derived(); 
    } 
} 

Теперь основной метод только печатает:

Base.foo() 
Смежные вопросы