java中的动态方法绑定 - 为什么这个方法?

时间:2016-02-15 18:39:31

标签: java inheritance

lli n;
cin>>n;
lli arr[size];
fi(i,n)
cin>>arr[i];
if(n==1)
    cout<<"0"<<endl;
else
{
    lli sum=0;
    for(lli i=n-1; i>0; i--)
    {
        if(arr[i]<arr[i-1])
        {
            lli k=abs(arr[i]-arr[i-1]);
            if(i==(n-1))
            {
                arr[i]+=k;
                sum+=k;
            }
            else
            {
                if((arr[i]+k)<=arr[i+1])
                    arr[i]+=k, sum+=k;
                else
                    arr[i-1]-=k, sum+=k;
            }
        }
    }
    cout<<sum<<endl;
}

有人可以解释为什么public class A { public void m1(A a) { System.out.println("m1(A) in A"); } public void m4() { System.out.println("m4() in A"); } } public class B extends A{ public void m1(B b) { System.out.println("m1(B) in B"); } public void m4() { System.out.println("m4() in B"); } } public class Test { public static void main(String[] args) { B b = new B(); A a = b; a.m1(b); // returns m1(A) in A a.m4(); // returns m4() in B } } 使用A的方法而a.m1(b)使用B的方法?

我特别不明白这个变量(a.m4())如何调用两个不同类的方法。我认为在运行时,a被视为A或B,然后应该导致A中的两种方法或来自B的两种方法。

2 个答案:

答案 0 :(得分:4)

这是因为element.getScreenshotAs(OutputType.FILE); File destination=new File("Image.png"); FileUtils.copyFile(null, destination); 没有覆盖B.m1(B)。它是一个重载,因为它的参数是一个不同的类型。

要覆盖它,您需要将参数类型更改为A.m1(A)

请注意,使用A注释您认为所覆盖的方法总是一个好主意:然后编译器会告诉您是否还没有?{0}真的压倒了这个方法。

另请注意,如果您致电@Override,则调用b.m1(b);上的方法,因为该重载更具体B。但是,使用当前代码,在编译时可以匹配的唯一方法是A.m1(A),因为所有已知的是A.m1(A)a的实例或其子类型之一:已知的唯一方法是A上的方法。

在编译时选择调用的方法,而不是运行时。

答案 1 :(得分:1)

让我们从对象声明的基础开始。

我们考虑一个班级Animal

Animal anim=new Animal();

Anim anim告诉JVM创建一个Animal类型的新引用变量,new Animal()要求JVM创建一个新的Animal对象。由=组合的这两个语句告诉JVM创建类型为Animal的引用变量,并为其分配动物对象。

anim是什么?

  • anim类似于控制Animal类型对象行为的遥控器。我们用它来引用这个对象。

我希望直到现在都很清楚。

现在让我们继续进行继承和多态。考虑一个扩展Dog的新类AnimalDog成为Animal的子类。

如果是继承,您可以考虑IS A规则。在这种情况下,由于Dog已延长AnimalDog为A Animal。我希望你能帮助我。这就是多态性出现的地方。多态性意味着您实际上可以使用超类引用变量来引用子类对象。

Animal anim1=new Dog();

我们创建了一个控制anim1对象的遥控器Dog。此anim1引用(远程控制)只能控制AnimalDog的特定方法。此遥控器还可以控制过度使用的方法,但无法控制Dog中未继承或过载的任何新方法。

现在,让我们继续您的课程ABB IS-A A,因为它已扩展A

这意味着多态性A a= new B();是正确的。这与您使用以下代码所做的类似:

B b=new B();
A a=b;

现在为什么a.m1(b);转到A中的方法 并a.m4();转到B

在开始之前,让我们先看看其他内容:

您在课程A中有一个方法: public void m1(A a)

您在课程B中有一个方法: public void m1(B b)

覆盖意味着您实际上正在重新定义子类中的继承方法。因此,在您的情况下,班级m1(B b)中的B并没有超越,因为它所具有的不同之处。它具有B类型的参数,而m1(A a)中的原始A查找类型A的参数。简而言之,您的班级B有两个名为m1的方法。 一个继承自A的新方法或带参数类型为B的重载方法。

就像我之前提到的,我们的遥控器a只能看到特定于类A的方法。它无法看到过载的方法。这就是原因,它实际上是继承的方法m1(A a)

现在,a.m4();转到m4()中的B。为什么呢?

  • 因为m4()中的B是一种过度使用的方法,a可以看到它。

如果您致电b.m1(b),则会使用B中的方法。

总结: 您可以使用超类引用变量/ remote来引用/指向子类对象,但是此远程只能看到包含过载而不是过载的继承方法。 但是子类类型的引用将能够看到所有方法。

帮助您识别过度使用和重载的方法:

过度使用的方法如下:

  • 参数必须相同且参数必须相同或兼容。
  • 方法不容易被访问。那是public无法private

重载方法如:

  • 返回类型可以不同。

  • 参数类型或参数数量应该有所不同。

  • 可以更改访问级别

使用上述规则,您可以轻松地认为m1(B b)B实际上是一个重载方法,因为参数类型与m1(A a)不同。

最后,B拥有3种方法:

  • m1(A a) inherted

  • m1(B b)重载

  • m4()过度使用

如果您有任何疑问或出现错误,请发表评论。