0

如果c是一个ChildClass对象,那么为什么它不能调用 的方法ChildClass?喜欢:

ParentClass c=new ChildClass(); //Here ChildClass extends ParentClass

尤其是:

Object s=new StringBuffer();

s是 的对象StringBuffer,但是s.append(null)是编译时错误。为什么这样?

4

5 回答 5

2

编译器的工作是确保您不调用任何与您调用它的变量不匹配的方法。为了帮助编译器,我们给所有变量一个“类型”。类型可能是像“int”这样的原始类型,也可能是类、枚举或接口。如果是类、接口或枚举;那么在该类、接口或枚举中列出的方法就是编译器允许您在该变量上使用的方法。

变量的“类型”不一定与变量引用的对象的“类”相同。在您的示例中,类型是Object,但类是StringBuffer。但是编译器使用类型而不是类来检查您的方法调用是否正常;因为不能期望编译器知道您可能使用变量来引用的每个对象的类。

如果语言不以这种方式工作,那么具有类型的变量就没有意义了。这就是 Javascript 的工作方式——一切都被声明为var并且没有真正的类型系统。当我们说 Java 是“静态类型的”时,我们的意思是我们必须给变量类型,这样做有助于编译器防止我们误用变量。

于 2014-09-06T04:03:23.077 回答
1

因为编译器不知道引用sStringBuffer在运行时引用的实例并且Java静态类型的语言

于 2014-09-06T03:57:58.943 回答
1

c被声明为ParentClass. 因此,编译器所知道的只是它是它的一个子类ParentClass某个子类。假设在c某处重新分配了一些其他语句:

c = new SomeOtherChildClass();

这是合法的,因为SomeOtherChildClass它也是 的子类ParentClass,并且您已经告诉编译器c可以是 any ParentClass。现在,如果编译器看到

c.methodOfChildClass();

它怎么知道那c是一个ChildClass而不是一个SomeOtherChildClass没有那个方法的?

PS如果你确定c真的是 a ChildClass,在某些时候,你可以让它ChildClass通过向下转换来调用一个方法:

((ChildClass)c).methodOfChildClass();

强制转换将导致编译器将其c视为ChildClass; 在运行时,程序将检查以确保c确实是 a ChildClass,否则程序将抛出ClassCastException.

于 2014-09-06T04:00:43.377 回答
0

您需要强制转换对象以使用实例的方法

Object s = new StringBuffer();
StringBuffer s2 = (StringBuffer) s;
s2.append(null);

尽管是 StringBuffer 的一个实例,它仍然是 Object 类型,并且 Object 没有方法 append

于 2014-09-06T04:02:38.910 回答
0

你必须将你的对象转换为 stringbuffer 类型,或者你必须像这样声明 s 对象 stringbuffer s =new stringbuffer() 然后你可以调用这个类的所有方法

于 2014-09-06T04:06:14.437 回答