为什么在子类对象中为超类变量存储或分配内存?

问题描述

:作为一般规则,如果类定义了子类可以访问的字段,则子类 不应 重新定义该字段。这真是个坏主意。首先,您所看到的是使 字段正常工作。重新定义子类中的非私有字段要求受到伤害。(当然,如果Joe编写Mammal而Mary编写Zebra并且Joe在某个时候添加了一个字段,Mammal而该字段恰好与Mary所使用的字段冲突Zebra,则Mary对此无能为力。这是将所有字段设为私有的原因之一。)

但是,即使在隐藏的情况下,为什么子类对象也存储超类变量的值。

这里的关键是要记住,字段不是多态的,只是方法。因此,对象中 必须 有两个name字段(一个来自from Mammal,一个来自fromZebra),因为使用A Mammal型引用的代码需要查看Mammal name,而使用ZebraA型引用的代码需要查看Zebraname

这就是为什么您的代码显示“ Furry bray”,然后显示“ stripes bray”的原因。你可以通过获得“毛茸茸的叫声”m,因为访问namem(一个Mammal-typed变量)访问Mammalname(不是多态),让您‘毛茸茸’。但是随后您makeNoise使用m并返回"bray"方法,因为调用方法是onZebra(多态的)方法。然后,您再次使用zZebra类型参考)进行操作,并看到“ stripes bray”,因为z访问Zebra的是name,而不是Mammal


您可能遇到的下一个问题是:如果我们将makeNoise两个类都更改为:

String makeNoise() { 
    return this.name;
}

为什么要ZooKeeper编码

  Mammal m = new Zebra();
  System.out.println(m.name + m.makeNoise());

  Zebra z = new Zebra();
  System.out.println(z.name + z.makeNoise());

从给我们“毛茸茸条纹” mstripes stripesz

这是相同的原因,只是它的表示形式不同。从类型引用m.name访问,因此看到的(不是多态的)。调用 方法(多态),以及里面的,有型,即使我们把它称为从-typed (等用途的)。在那里使用Zebra的事实以及在代码中键入内容的事实都是Java多态性的关键。name``Mammal``Mammal``name``m.makeNoisemakeNoise``Zebra``makeNoise``this``Zebra``Mammal``m``this.name``Zebra``name``makeNoise``this``Zebra``Zebra

让我们更进一步:如果Zebra根本没有定义makeNoise怎么办?

class Mammal {
    String name = "furry ";
    String makeNoise() { 
        return this.name;
    }
}

class Zebra extends Mammal {
    String name = "stripes ";
}

现在,我们从中获得“毛茸茸” m和“条纹毛茸”z。其原因与上述相同:引用的类型确定使用哪个字段,并且在Mammal代码makeNoise)中this具有类型Mammal。因此,即使我们调用makeNoiseusingz,由于Zebra没有makeNoise,也Mammal被称为,所以查找的引用name具有类型Mammal

有什么用吗?

这是 正常工作,特别是在私人领域的情况下类。Mammal代码不必担心子类会出现并重新定义其字段。您可能有一个10级深的类层次结构,每个类都定义了自己的name,这很好,每个级别的代码都可以使用name它定义的。

解决方法

在以下代码中-

class Mammal {
  String name = "furry ";
  String makeNoise() { 
    return "generic noise";
 }
}

class Zebra extends Mammal {
    String name = "stripes ";
    String makeNoise() { 
        return "bray"; 
    }
}

public class ZooKeeper {
    public static void main(String[] args) { 
       new ZooKeeper().go();
   }

   void go() {
      Mammal m = new Zebra();
      System.out.println(m.name + m.makeNoise());

      Zebra z = new Zebra();
      System.out.println(z.name + z.makeNoise());
   }
}

如果在eclipse的调试窗口中看到,则两个对象(mz)都包含name变量(furrystripes)的两个值。

我确实知道在多态中,子类也可以使用超类的泛型方法。但是,即使在隐藏的情况下,为什么子类对象也存储超类变量的值。有什么用吗?

猜你在找的技术问答相关文章

如何检查配对的蓝牙设备是打印机还是扫描仪(Android)
是否允许实体正文进行HTTP DELETE请求?
如何将ZipInputStream转换为InputStream?
java.util.logging Java 8中的变量
PowerMockito.doReturn返回null
Java中的RESTful调用
Swing / Java:如何正确使用getText和setText字符串
特殊字符和重音字符
Android Studio中的ndk.dir错误
错误“找不到主类”