2015-10-13 2 views
3
public class ExampleClass { 

    public static void main(String[] args) { 

     // Upcasting from subclass to super class. 
     A aRef=new C(); 

     //aRef.setMessage(); compilation Error  
     aRef.display(); 

     B bRef = (B)aRef; 
     //bRef.setMessage(); compilation Error 
     bRef.display(); 

     C cRef = (C)aRef; 
     cRef.setMessage("ayaz"); 
     cRef.display(); 
    } 
} 

interface A 
{ 
    void display(); 
} 

class B implements A 
{ 

    public void display() { 
     System.out.println("Am in class B"); 
    } 

} 

class C extends B 
{ 
    String msg = "Am in class C"; 
    @Override 
    public void display() { 
     System.out.println(msg); 
    } 
    public void setMessage(String s){ 
     msg = s; 
    } 

} 

В приведенной выше коде после того, как объект AREF понижающего приведения к объекту типа B не в состояние назвать setMessage(), хотя на вызов дисплея с НДТ Obj, способ отображения класса C называется. Когда мы опускаемся в Obj of C, тогда мы можем назвать, почему? это aRef, указывающий только на объект типа C, я думаю, что ссылка не копируется.вниз литья объекта и вызов метода

ответ

0

Хотя объект, который находится в куче, имеет класс C, ссылка, которую вы использовали, относится к типу B. Вы можете вызывать только методы, которые существуют в ссылке, а не методы, присутствующие в фактическом объекте.

1) Только класс C имеет setMessage method.So только ссылка на объект С может вызвать эту method.Alternatively вы можете определить эти методы в интерфейсе и класс B и марка класс B, как абстрактные с конкретной реализацией в классе C

public class ExampleClass { 

    public static void main(String[] args) { 

     // Upcasting from subclass to super class. 
     A aRef=new C(); 

     aRef.setMessage(); //No compilation Error now  
     aRef.display(); 

     B bRef = (B)aRef; 
     bRef.setMessage(); //No compilation Error now  
     bRef.display(); 

     C cRef = (C)aRef; 
     cRef.setMessage("ayaz"); 
     cRef.display(); 
    } 
} 

interface A 
{ 
    void display(); 
    void setMessage(String s); 
} 

abstract class B implements A 
{ 

    public void display() { 
     System.out.println("Am in class B"); 
    } 

} 

class C extends B 
{ 
    String msg = "Am in class C"; 
    @Override 
    public void display() { 
     System.out.println(msg); 
    } 
    public void setMessage(String s){ 
     msg = s; 
    } 

} 
2

две вещи:

  • в время компиляции компилятор смотрит на тип ссылки, чтобы определить, является ли метод существует (по крайней мере объявлена). Таким образом, aRef.display() указан как bRef.display() и cRef.display(). Но aRef.setMessage() и bRef.setMessage() неверны (setMessage не метод, объявленный или определено в A или B. Конечно cRef.setMessage() правильно.
  • в выполнения машина находит правильный метод для выполнения. Как aRef, bRef и cRef см тот же C объект, который переопределяет метод display, этот называется
0

простое правило:.

  • Тип переменной говорит, что может быть сделано
  • Тип объекта рассказывает, как сделать это
+0

'тип переменной:' определить, как будут представлены и хранятся данные. 'тип объекта:' определять поведение объекта по методу, по существу, то, что можно выполнить с помощью определенного объекта. – YoungHobbit

+0

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

Смежные вопросы