“类变量的类型决定了可以与该变量一起使用的方法名称”。这意味着什么?

时间:2019-02-27 19:34:23

标签: java

我目前正在研究多态性,但我不理解以下陈述:

“类变量的类型决定了可以与该变量一起使用的方法名称。 但是,由变量命名的对象将确定使用具有相同方法名称的定义。”

我很困惑。

4 个答案:

答案 0 :(得分:1)

这意味着您可以从一个对象调用的方法受到该对象类型的限制。例如,假设您具有以下类:

public class Animal {
    public void sayName() {
        System.out.println('animal');
    }
}

public class Cow extends Animal {
    @Override
    public void sayName() {
        System.out.println('cow');
    }

    public void sayMoo() {
        System.out.println('mooo');
    }
}

现在,您可以像这样声明您的母牛了:

Animal cow = new Cow();

您可以这样做,因为CowAnimal的子类。但是,如果这样做,您将无法与Cow说声mo,因为您已将变量创建为简单的Animal。因此,无法从变量访问方法sayMoo

答案 1 :(得分:1)

  

类变量的类型决定了该变量可以使用哪些方法名称。

这意味着,如果您有一个Base类和一个Base类型的变量:

Base base = ...

您可以调用方法

base.method()

仅在类method()(或Base的超类)中定义了Base时。

  

但是,由变量命名的对象将确定使用哪个具有相同方法名称的定义。

这意味着调用base.method()并不总是执行类method()的{​​{1}}。

例如,如果Base是扩展类Derived并覆盖Base方法的类,则method()引用的实例的实际类型为{ {1}}:

base

然后打电话

Derived

将执行Base base = new Derived(); 的{​​{1}}的类实现。

“类变量的类型”是指引用变量的静态(编译时)类型。

“由变量命名的对象”是指变量引用的实例(对象)的动态(运行时)类型。

答案 2 :(得分:1)

请考虑以下代码(及其内部说明):

class A {
   public void methodA() {
       System.out.println("A -> A");
   }
   public void methodB() {
       System.out.println("A -> B");
   }
}

class B extends A {
   @Override
   public void methodB() {
       System.out.println("B -> B");
   }
   public void methodC() {
       System.out.println("B -> C");
   }
}

A a = new B(); 

// here, the type of variable a determines which methods can be called on that var.
// A declares two methods, methodA and methodB and only those can be called.
// Even a is actually referring to an instance of B which declares methodC
// as well, the call a.methodC() is not valid because a has type A.
a.methodA(); // prints A -> A

// Here, the actual implementation (the object that a refers to) determines 
// which implementation is being called and because the actual object 
// is an instance of B, we get B -> B printed.
a.methodB(); // prints B -> B
// a.methodC(); cannot be called

答案 3 :(得分:0)

简单起见,您将能够执行特定于您的类变量而不是类实例的方法。

通过这种方式,您可以将接口用作声明的类变量并实例化新对象。

Display display = new TV();

您将能够执行Display所具有的任何方法,但不能执行电视所具有的特定方法。