Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.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_Compiler Construction_Polymorphism - Fatal编程技术网

理解Java继承

理解Java继承,java,inheritance,compiler-construction,polymorphism,Java,Inheritance,Compiler Construction,Polymorphism,给定以下Java代码: class mainul { public static void main(String[] args) { /*block 1*/ B b1 = new B(); A a1 = b1; a1.m1(b1); /*block 2*/ B b2 = new B(); B a2 = b2; b2.m1(a2); } } class A {

给定以下Java代码:

class mainul {

    public static void main(String[] args) {

    /*block 1*/
        B b1 = new B();
        A a1 = b1;
        a1.m1(b1);

    /*block 2*/
        B b2 = new B();
        B a2 = b2;
        b2.m1(a2);
    }
}

class A {

    public static void p(Object o) {
        System.out.println(o.toString());
    }

    public void m1(A a) {
        p("m1(A) in A");

    }
}

class B extends A {

    public void m1(B b) {
        p("m1(B) in B");
    }
}
有人能解释一下为什么这个程序的输出是

m1(A) in A
m1(B) in B
由于a1的动态类型为B,人们会期望块1的输出为“B中的m1(B)”。我注意到A和B中m1的函数签名不匹配(一个期望类型为A的对象,另一个期望类型为B的对象作为其参数)A中的方法似乎获得了优先级,但无法真正将其链接到我的输出,因为它似乎与block2的输出不一致

感谢您的时间

正如您所注意到的,
B.m1(B)
不会覆盖
A.m1(A)
,因为它们采用不同的参数(尝试添加
@override
注释,您将看到编译器的抱怨)。因此,它永远不能通过引用
a
来调用


但是,可以通过引用a
B
调用它。正如奥利所说,这两种方法签名是不同的

当你在这里给他们打电话时:

    B b1 = new B();
    A a1 = b1;
    a1.m1(b1);

    /*block 2*/
    B b2 = new B();
    B a2 = b2;
    b2.m1(a2);

首先传递一个类型为A的对象,然后传递一个类型为B的对象。这是Java在此上下文中所关心的全部内容,它不关心对象的来源,只关心对象是什么。

所调用的方法是在编译时设置的(在本例中是A.m1(A))。我知道你认为它是动态的,对吧?动态绑定是运行时绑定。是的,但它只对A.m1(A)上的方法是动态的。所以A的任何子类都可以提供一个替代实现,但是它的签名必须相同,否则这是一个重载方法,而不是相同的方法

这也意味着动态绑定不考虑调用中使用的参数。方法名和形式签名在编译时设置。更改类型,它就不是同一个方法,也不会被调用

您可以执行此操作以强制编译器查看该方法:

a1.m1( (A)b1 )

这将告诉编译器您试图调用的方法。

只需按照以下代码操作即可:

块1

第2区


另外,如果您希望块1中的“m1(B)在B中”,只需将类A中的方法标记为virtual并重写类B中的方法。

另外,通过设置它的方式,您是否打算为每个对象使用
toString
方法,然后将对象传递给您的
p(object o)
方法
B b1 = new B();   //- variable  b1 (type is B) points to instance of B() 

A a1 = b1;        //- variable  a1 (type is A) points to instance of B() .. same as b1 is
                  // pointing to.

 a1.m1(b1);       // Call Method m1 on a1 (i.e. of class A ) ..IMP catch > as a1 holds
                  // object of b1, if there is method in Class A which is overriden in B,
                  // call that overriden method. But here method m1() is not overriden 
                  // by B  it will call method of class A.
B b2 = new B();  // variable b2 (type B) points to instance of B()

B a2 = b2;       // variable a2 (type B) points to same instance as b2 is pointing to.

b2.m1(a2);       // call method m1 of b2 (of class B). There is only one method m1 in b2
                 // and b2 holds object of B, it must call method of class B