Java 当您执行一件事时,实例变量调用是如何工作的=new B();其中B是a的一个子类?
这可能在某个地方得到了回答,但我不知道该搜索什么。假设你有以下几点 超类,Animal.javaJava 当您执行一件事时,实例变量调用是如何工作的=new B();其中B是a的一个子类?,java,Java,这可能在某个地方得到了回答,但我不知道该搜索什么。假设你有以下几点 超类,Animal.java public class Animal { public String noise = "squeak"; public String toString() { return noise; } } 子类Lion.java public class Lion extends Animal { public String noise = "ROAR!!"; public String
public class Animal {
public String noise = "squeak";
public String toString() { return noise; }
}
子类Lion.java
public class Lion extends Animal {
public String noise = "ROAR!!";
public String toString() { return noise; }
}
主类Runner.java
public class Runner {
public static void main(String[] args) {
Animal a = new Animal();
System.out.println(a);
System.out.println(a.noise);
Lion b = new Lion();
System.out.println(b);
System.out.println(b.noise);
Animal c = new Lion();
System.out.println(c);
System.out.println(c.noise);
}
}
输出为:
squeak
squeak
ROAR!!
ROAR!!
ROAR!!
squeak
为什么c.noise返回时发出吱吱声?实例方法调用和实例变量之间有什么区别,一个返回您期望的值,另一个不返回?为什么Java会这样做
谢谢简短回答:
可以重写方法,但不能重写字段
长答覆:
每个类都可以看到自己和父类的方法和字段(私有方法除外)。如果子实例使用与父类中的方法名称相同的方法,则此方法将被重写。如果在子实例上调用此方法(甚至从父实例的方法之一调用),则将使用全新的方法,而不是父实例的方法。孩子仍然可以通过super.method(…)
call调用他上一个父母的原始方法
但当我们来到田野时,情况就不同了。如果子类声明了一个新字段,该字段的名称与父类中的字段完全相同,那么它将只隐藏父类的字段而不重写,就像局部变量隐藏全局字段一样。因此,子方法只会看到子方法的字段,但是父方法将继续看到父方法的字段,并且子方法的字段在父类中无论如何都不可见-这就是您得到的
子项可以通过((父项)此项)访问其父项的字段。字段
详细回答:
所以你要做的就是这样定义Lion:
public class Lion extends Animal {
public Lion() {
noise = "ROAR!!";
}
}
现在,对于Lion实例,Animal的noise成员变量已更新为ROAR
当然,你(几乎)永远不会在像野外那样的类上拥有一个公共可变成员。你不能覆盖字段,新的
noise
声明在Lion
中隐藏了父类的noise
属性。这样做:
public class Lion extends Animal {
// public String noise = "ROAR!!"; // <---- Remove this line
public Lion() {
noise = "ROAR";
}
public String toString() {
return noise;
}
}
公共类动物{
//public String noise=“ROAR!!”;//默认情况下,java中的所有非静态方法都是有效的。除非它们被标记为final(这使得该方法不可重写).Java使用a来调用正确的对象的方法。这是因为Java只谈到方法的重写。成员变量只能在子类中隐藏。因此,当您说c.noise时,它实际上将父类中的字符串变量称为c if引用类型动物。您感兴趣的主题是基本上,根据设计,Java允许重写方法(假设它们是非最终的)JVM将在运行时执行适当的实现。此多态属性仅提供给方法。良好的OO设计将规定字段无论如何都要封装。我不是Java专业人士,所以我不会将此称为答案,但区别在于Java中的方法是虚拟的。也就是说,当您调用c.toString()时,Java通过使用查找表知道正确使用的方法是Lion's toString()。但是,这种虚拟化不会发生在实例变量上。大多数人在说“类方法/字段”时指的是静态方法/字段,但我很确定您在这里指的是实例方法/字段。