0

Heres the code :

package com.java2.javaapplication2;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.

/**
 *
 * @author Ajinkya
 */
class A{
    int data1=10;
    void show1(){
        System.out.println("In A="+data1);
    }
}

class B extends A{
    int data2=20;
    void show2(){
        System.out.println("In B="+data2);
    }



}


public class Overriding6 {
    public static void main(String args[]){
        A a=new B();
        System.out.println("Data1="+a.data1);
        System.out.println("Data2="+a.data2);
        a.show1();
        a.show2();
    }
}

Please explain A a=new B(); and what variables and methods are accessible by a ? this technique is called polymorphic reference right, but how does it work under influence of inheritance ?

4

2 回答 2

0
System.out.println("Data2="+a.data2);

这不能做,java是这样工作的

编译器查看您的左侧(变量),并据此知道它可以访问哪些方法(其中 data2 在您的变量所引用的类 A 中找不到),

但在运行时,JVM 在堆上查看真实创建的对象(通过“new”关键字),即

new B();

因此,它采用编译器选择的方法,并根据内存中的可用对象在运行时实现它

所以 ....

A a = new B();

你首先声明一个你想要的任何类型的变量(A),这样你就可以访问它的任何可能的方法或变量

并且编译器正在等待您将任何通过 IS-A 测试的对象分配给此变量类型,并且由于 B 扩展了 A,因此它是 IS-A“A”,任何子类 IS-A 超类

所以编译器接受这个赋值

此技术用于使同一方法 throw 子类的不同实现(使用)受益,例如:

这些是在体育场进行的运动种类和门票价格

class Sport{ int getTicketPrice(){ return 0;}}
class Basketball extends Sport{ int getTicketPrice(){return 10;}}
class Football extends Sport{ int getTicketPrice(){return 20;}}

假设这是体育场售票系统的一部分,并且有一个班级根据人们想参加的运动类型来确定票价,所以它会有这样的方法

class Tickets{ int getPrice(Sport sport){return sport.getTicketPrice();}}

如果没有多态性(IS-A / 继承),我们将需要创建 3 个门票类,每个类都有一个 getPrice() 方法,该方法将我们的 3 个类(运动、篮球、足球)中的每一个作为参数,但是

编译器将允许您使用 Sport 类的任何子类,因为它确定 Sport 类(及其所有子类)具有名为“getTicketPrice()”的方法,并且如果子类没有覆盖(更改实现/使用这个方法和这个例子一样),原来的方法将被实现

所以,编译器端检查方法,JVM决定这个方法的真实结果,回到我们的例子,我们将有一个类来运行系统的这一部分,一个类负责获取运动的类型,以及检查它的票价,然后将其显示给用户,因此该课程的一部分将是

class BasketballBoxOffice{
    Tickets tickets = new Tickets();
    Sport sport = new Basketball();

    // this is a method that runs when ever the Tickets Seller clicks 
    // on Print Ticket Button on the Screen        

    void printTicket(){
        // some code
        System.out.println(tickets.getPrice(sport));
        // some code        
    }

    // more code
}

现在使用相同的系统,在这个体育场足球区的票房上,你不需要新的课程,而只需要一个“多态性”

class FootballBoxOffice{
    Tickets tickets = new Tickets();
    Sport sport = new Football();    // thats all the difference

    // this is a method that runs when ever the Tickets Seller clicks 
    // on Print Ticket Button on the Screen        

    void printTicket(){
        // some code
        System.out.println(tickets.getPrice(sport));
        // some code        
    }

    // more code
}

由于多态性(继承),无需更改代码的任何内容,只需子类化任何类,并为其方法创建自己的实现,并使用它

希望这不是我的愚蠢解释

于 2013-09-04T22:14:26.037 回答
0

在 java 中,方法(行为)调用是在运行时根据运行时真实对象类型解析的,称为动态方法分派或后期绑定或动态绑定。但是属性(成员变量)调用不是基于运行时真实对象解析的,而是基于引用类型解析的。在你的情况下:

  1. 超类引用可以保存子类对象,通过这个引用,您可以调用超类的所有方法和子类已知的方法(至少在超类中声明)给超类。
  2. 当您访问任何类成员变量时,它与真实对象无关,并且根据引用类型进行访问。

因此,您不能使用类 A 的引用调用 show2(),因为超类 A 不知道此方法。您也不能使用超类 A 的引用访问 data2 变量,因为对成员变量的调用是根据引用类型解析的,并且通过任何引用调用成员变量,它应该在该引用类型的接口/类中声明(已知)

于 2013-08-24T06:37:45.077 回答