Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的动态方法调度_Java_Inheritance_Casting - Fatal编程技术网

java中的动态方法调度

java中的动态方法调度,java,inheritance,casting,Java,Inheritance,Casting,在上面的程序中,我尝试调用aObj.b 1.为什么我不能通过aObj访问该变量,尽管它引用的是B类?? 2.为什么我能够访问show()方法 aObj是a类型的局部变量A没有名为b的成员,该成员仅在子类b中。如果要使用b,则需要声明类型为b的变量,但当然,您只能为其分配b的实例(或子类,如果有的话) A声明了一个方法show(),但是您重写了子类B中的实现,您必须区分aObj的静态类型和aObj的运行时类型 代码,例如 class A{ int a=10; public void show

在上面的程序中,我尝试调用aObj.b
1.为什么我不能通过aObj访问该变量,尽管它引用的是B类??

2.为什么我能够访问show()方法

aObj
a
类型的局部变量
A
没有名为
b
的成员,该成员仅在子类
b
中。如果要使用
b
,则需要声明类型为
b
的变量,但当然,您只能为其分配
b
的实例(或子类,如果有的话)


A
声明了一个方法
show()
,但是您重写了子类
B

中的实现,您必须区分
aObj
静态类型和
aObj
运行时类型

代码,例如

class A{
int a=10;   
public void show(){ 
    System.out.println("Show A: "+a);
    }
}

class B extends A{
public int b=20;    
public void show(){
    System.out.println("Show B: "+b);
    }
}



public class DynamicMethodDispatch {

    public static void main(String[] args) {

    A aObj = new A();       
    aObj.show();    //output - 10

    B bObj = new B();
    bObj.show();   //output - 20

    aObj = bObj;   //assigning the B obj to A..         
    aObj.show();  //output - 20 

    aObj = new B();
    aObj.show();  //output - 20
             System.out.println(bObj.b);  //output - 20 
    //System.out.println(aObj.b); //It is giving error



     }
}
结果产生一个
aObj
变量,该变量具有静态类型
A
和运行时类型
B

编译器在决定允许或不允许什么时,只会考虑静态类型

关于你的问题:

1.为什么我不能通过aObj访问该变量,尽管它引用的是B类

因为(通常)编译器无法知道
aObj
在运行时将引用
B
对象,只能知道它将引用某种形式的
a
对象。由于
.b
在所有
A
对象上都不可用,因此编译器会认为“安全总比抱歉好”,而不允许它

2.为什么我能够访问show()方法


因为此方法在所有
A
对象中都可用(如果未在子类中声明,则仍从
A
继承)。

方法和字段具有不同的多态行为

将调用的方法是实例的运行时类型的方法

A aObj = new B(); 
将被调用的字段是您声明的引用类型的字段

aObj=new B(); //new B()
即使A中没有show()方法,下面的方法也可以

A aObj = new A(); // A aObj

这种行为称为
虚拟方法调用
,它是Java中
多态性
的一个重要方面。你应该看看这个

  • 因为A里面没有变量b,即使当你把b传递给A时,你仍然有一个里面没有变量b的对象。因此,尝试访问b将导致编译时错误

  • 在show()的情况下,A和B都有这个方法,所以您在这里所做的实际上是在运行时重写它。这只不过是一个问题。因此,由于A已经有了show()方法,并且稍后会被B覆盖

  • A=新的B(); a、 show()


    这将在运行时运行B的show()方法。

    但是它是如何访问B的show()的呢?aObj=bObj;aObj.show()//output-20是bA的值,它声明了一个方法
    show()
    ,但是您重写了子类
    B
    中的实现。您可能应该进一步研究OO/继承的概念。。我明白了…是的,我的opp原则真的很差。。在哪里阅读OOP原则?推荐一些好的网站。。谢谢,我没这么做,老兄。。。相信我。。我也没有足够的理由去做。你回答的前4行对我来说是无价的。谢谢。我在JAVA中查看了这个示例,如果我尝试一个aobj=new B()然后是aobj.show(),那么编译器会给出一个错误,要求我在
    aObj = new B();
    aObj.show(); //calls B's show()
    
    class A{ // class A has variable a and method show();
    int a=10;   
    public void show(){ 
        System.out.println("Show A: "+a);
        }
    }
    
    class B extends A{ //class B inherits variables and methods of A.
       // so class B has variable a, b and show(). Also, show is overridden by class B.
    public int b=20;    
    public void show(){
        System.out.println("Show B: "+b);
        }
    }