如何使用实例化变量隐藏接口变量
我在使用实例化变量映射接口变量时遇到了一些麻烦。我知道如何通过重写方法并在方法中手动分配变量来完成此操作,但无法弄清楚如何使用任何对象的实例变量调用该方法。如何使用实例化变量隐藏接口变量
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);
}
}
此代码将输出“鲍勃震动加布的手。”有没有什么办法可以阻止它引用接口名称“Gabe”,而是引用实例名称“Sally”,以便让“Bob握住Sally的手”?
撇开对编码风格和干净的代码的问题,这是为什么你的代码始终打印“......震撼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对字符串(在其它类)”。
另一件事:即使在程序的所有实现中,实现类中都有一个“名称”变量:在编译时,编译器不知道运行时是否仍然如此。您的JAR可能被用于另一个定义了“UnnamedShakesHand”类的程序(没有“名称”变量)。那么应该发生什么?如果实现类与另一个类定义了“名称”,那么应该如何处理您的代码?它应该抛出一个“ClassCastException”,因为你的“String othersName = other.name;”指令?
长话短说: 在“ShakesHands”界面中引入了“String getName()”方法。每个实现类都可以返回其名称的变量值,并且一切都很好。
另外,请遵循编码约定。常量应该拼写成'NAME',混淆会消失。 –
为什么'ShakesHands'首先有一个'name'? –
我会使用访问器(setters和getters)而不是直接访问字段。你的例子相当可疑;我想不出这种编码风格的有效用法。 – markspace
如果我没有给ShakesHands分配一个名字,我会得到一个“名称无法解析或不是字段”的错误 –