2009-08-28 6 views
12

У меня есть два вопроса по этому кодуСмешение «переопределить частный метод»

public class Override { 
    private void f() { 
     System.out.println("private f()"); 
    } 
    public static void main(String[] args) { 
     Override po = new Derived(); 
     po.f(); 
    } 
} 

class Derived extends Override { 
    public void f() { 
     System.out.println("public f()"); 
    } 
} 

/* 
* Output: private f() 
*/// :~ 

1) Как функция F видна на обращения Override ро;

2) Почему выход «частный е()»

+0

Но как ссылка с объектом подкласса может вызвать частный метод суперкласса ??? это ошибка? –

+0

Нет, это не ошибка, это точно так, как должно работать. – Jesper

+0

, но это не нарушает правила наследования и позднего связывания. –

ответ

24
  1. main метод находится внутри класса Override, так конечно, он может видеть частные члены класса Override.

  2. Вы не наиважнейшего метод f в классе Derived, нет полиморфизма. Тип переменной po составляет Override, поэтому он примет метод f от класса Override.

Обратите внимание, что в классе Override метод f не виден на всех в классе Derived. Метод f в классе Derived - это другой метод, который не имеет никакого отношения к методу f в суперклассе.

+0

Но когда привязка выполняется во время выполнения, тогда po будет иметь объект класса Derived, чтобы он мог вызвать частный метод суперкласса. –

+3

Нигде в вашем коде есть вызов частного метода суперкласса. Когда вы вызываете po.f(), вызывается f Override, потому что тип времени компиляции po является Override. Поскольку нет переопределения, нет динамического связывания (без полиморфизма). Java не смотрит на тип во время выполнения. – Jesper

2
Override po = new Derived(); 
po.f(); 

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

Derived po = new Derived(); 
po.f(); 

Thsi правильный код, который будет вызывать производный-х е

+0

Вопрос о Java, а не C#. «virtual» не существует на Java. – Jesper

+0

Спасибо за комментарий, я также установил answwer. –

0

Переопределение метода имеет три conditions.child класс должен имеет такое же имя и параметры и возвращаемое значение в качестве своего супер class.But если оба параметр и возвращаемое значение имеют меняются, поэтому коррекция не существует, даже если два метода отличаются метод хорошо, как это:!

public class Parent { 
      public int addV(int a,int b){ 
     int s; 
     s = a + b; 
     return s; 
    } 
} 

class Child extends Parent{ 
    public void addV(){ 
     //do...something 
    } 
} 

Затмение не будет говорить об ошибке! потому что метод addV в классе Child отличается от метода addV в классе Parent.As ваш экземпляр!

+0

Только имя и список аргументов метода должны быть точно такими же. Возвращаемое значение дочернего элемента может быть подклассом возвращаемого значения родителя. И еще два правила, которые вы опустили. Метод у ребенка должен быть как минимум таким же доступным, как и у родителя. А подкласс не может генерировать новые проверенные исключения или более широкие. – pkkoniec