Java 如何使用实例变量对接口变量进行阴影处理
我在用实例变量跟踪接口变量时遇到了一些问题。我知道如何通过重写方法并在方法中手动分配变量来实现这一点,但我不知道如何使用调用该方法的任何对象的实例变量Java 如何使用实例变量对接口变量进行阴影处理,java,interface,Java,Interface,我在用实例变量跟踪接口变量时遇到了一些问题。我知道如何通过重写方法并在方法中手动分配变量来实现这一点,但我不知道如何使用调用该方法的任何对象的实例变量 public interface ShakesHands { static final String name = "Gabe"; public void shakeHands (ShakesHands other); } class Student implements ShakesHands{ String n
public interface ShakesHands {
static final String name = "Gabe";
public void shakeHands (ShakesHands other);
}
class Student implements ShakesHands{
String name;
@Override
public void shakeHands(ShakesHands other) {
String othersName = other.name;
System.out.println(name + " shook " + othersName + "'s hand.");
}
}
class Parent implements ShakesHands{
String name;
@Override
public void shakeHands(ShakesHands other) {
String othersName = other.name;
System.out.println(name + " shook " + othersName + "'s hand.");
}
}
public class App {
public static void main(String[] args) {
Student student1 = new Student();
student1.name = "Bob";
Parent parent1 = new Parent();
parent1.name = "Sally";
student1.shakeHands(parent1);
}
}
这段代码将输出“Bob Shaked Gabe's hand”。我有没有办法阻止它引用接口名“Gabe”,而是引用实例名“Sally”,这样我就得到了“Bob Shaked Sally's hand”?抛开关于编码风格和干净代码的问题,下面是为什么代码总是打印“…Shaked Gabe's hand.” 握手的方法实现引用来自ShakesHands实例的“名称”,而不是其中一个实现类。由于ShakesHands中唯一的“名称”在这里是“在范围内”,因此最终总是使用值为“Gabe”的静态变量 实际上,编译器最好始终使用静态变量值,而不是使用实现类的变量(如果存在此类变量)。派生类或实现类中的数据类型不要求与超类/接口中的数据类型相同,因此您可以让ShakeHand的名称与学生名称的类型不同 例如:
public interface ShakesHands {
String name = "Gabe";
public void shakeHands(ShakesHands other);
}
class Student implements ShakesHands {
Integer name = Integer.valueOf(0);
@Override
public void shakeHands(ShakesHands other) {
System.out.println(name.getClass().getSimpleName() + " (in this class) with value "+name+" vs. " + other.name.getClass().getSimpleName()+" (in other class) with value "+other.name);
}
}
在我的示例调用中,printet文本是“值为7的整数(在这个类中)与值为Gabe的字符串(在另一个类中)”
另一件事:即使在程序的所有实现中,实现类中都有一个“name”变量:在编译时,编译器不知道在运行时是否仍然是这样。您的JAR可能用于另一个定义了“unnameshakeshand”类(没有“name”变量)的程序中。那么会发生什么呢?如果实现类使用另一个类定义了“name”,那么代码会发生什么变化?它是否应该因为您的“字符串othersName=other.name;”指令而抛出一个“ClassCastException”
长话短说:
在“ShakesHands”接口中引入一个“String getName()”方法。每个实现类都可以返回其名称的变量值,一切正常。抛开关于编码风格和干净代码的问题不谈,下面是为什么您的代码总是打印“…握着Gabe的手”。: 握手的方法实现引用来自ShakesHands实例的“名称”,而不是其中一个实现类。由于ShakesHands中唯一的“名称”在这里是“在范围内”,因此最终总是使用值为“Gabe”的静态变量 实际上,编译器最好始终使用静态变量值,而不是使用实现类的变量(如果存在此类变量)。派生类或实现类中的数据类型不要求与超类/接口中的数据类型相同,因此您可以让ShakeHand的名称与学生名称的类型不同 例如:
public interface ShakesHands {
String name = "Gabe";
public void shakeHands(ShakesHands other);
}
class Student implements ShakesHands {
Integer name = Integer.valueOf(0);
@Override
public void shakeHands(ShakesHands other) {
System.out.println(name.getClass().getSimpleName() + " (in this class) with value "+name+" vs. " + other.name.getClass().getSimpleName()+" (in other class) with value "+other.name);
}
}
在我的示例调用中,printet文本是“值为7的整数(在这个类中)与值为Gabe的字符串(在另一个类中)”
另一件事:即使在程序的所有实现中,实现类中都有一个“name”变量:在编译时,编译器不知道在运行时是否仍然是这样。您的JAR可能用于另一个定义了“unnameshakeshand”类(没有“name”变量)的程序中。那么会发生什么呢?如果实现类使用另一个类定义了“name”,那么代码会发生什么变化?它是否应该因为您的“字符串othersName=other.name;”指令而抛出一个“ClassCastException”
长话短说:
在“ShakesHands”接口中引入一个“String getName()”方法。每个实现类都可以返回其名称的变量值,一切正常。为什么
ShakesHands
首先有一个name
?我会使用访问器(setter和getter),而不是直接访问字段。你的例子很可疑;我想不出这种编码风格的有效用途。如果我没有为ShakesHands指定名称,我会收到“名称无法解析或不是字段”错误,然后不要尝试访问ShakesHands
参考值上的name
字段。您正在反向操作。请使用@markspace推荐的方法。为什么ShakesHands
首先有一个名称
?我会使用访问器(setter和getter),而不是直接访问字段。你的例子很可疑;我想不出这种编码风格的有效用途。如果我没有为ShakesHands指定名称,我会收到“名称无法解析或不是字段”错误,然后不要尝试访问ShakesHands
参考值上的name
字段。您正在反向操作。请使用@markspace推荐的方法。此外,请遵循编码约定。常量的拼写应该是NAME
,这样就不会有混淆了。另外,请遵循编码约定。常量应该拼写为名称
,这样混淆就消失了。