对象是通过对象引用变量(reference variable)来访问的,该变量包含对对象的引用。(--《Java语言程序设计》)
弄明白了引用数据类型、引用变量、对象之后,在慕课网上学习(课程《全面解析Java注解》第2章第1节)Java自带的注解@Deprecated, 遇到了下面的问题。
- 接口:Person;
- 实现类:Child;
- 测试类:AnnoTest;
Person接口:
package AnnotationDemo;
public interface Person {
public String name();
public int age();
//如果觉得这个方法在接口中定义得不太适合但是又不能直接删除掉(因为可能别的类在实现使用),可使用@Deprecated注解,表示该方法已经过时
@Deprecated
public void sing();
}
package AnnotationDemo;
public class Child implements Person {
@Override
public String name() {
// TODO Auto-generated method stub
return null;
}
@Override
public int age() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void sing() {
// TODO Auto-generated method stub
System.out.println("This child will sing a song!");
}
}
AnnoTest测试类:
package AnnotationDemo;
public class AnnoTest {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
// TODO Auto-generated method stub
//1 接口类型,有警告,需忽略
Person p = new Child();
p.sing();
//2 实现类类型,无警告
Child p2 = new Child();
p2.sing();
}
}
问题出在AnnoTest类中, 引用变量是不同的类型,警告的情况就 不一样。
当前的理解是这样的:
new Child()创建了Child类的实例化对象,变量p引用了这个Child类的对象,所以p是引用变量,而p前面的类名则表明p的类型,即是Person类型或者Child类型。
Person类型下的方法已经过时,而Child类型依然实现了这个方法(注意这里的“过时”的意思,老师讲的时候是说sing()方法定义得不太合适,因为有些类根本不需要实现这个方法,就像有些人不会唱歌,但是标准里却有唱歌这个标准)。所以如果要将引用变量声明为Person类型并去调用过时的sing()方法是不合适的,所以要有警告;然而就像有些人还是很会唱歌的,若声明为Child类型的并去调用sing()方法,它不仅会唱,唱得还非常好,是再合适不过了,所以就无需警告。我觉得还是要理解“过时”的含义,过时不是错,只是不适用于大多数。
现在的理解还不透彻,以上理解也可能有偏差甚至不对。以后会关注这个问题。