Java 子类的对象无法调用其自己的方法
如果Java 子类的对象无法调用其自己的方法,java,inheritance,casting,extends,upcasting,Java,Inheritance,Casting,Extends,Upcasting,如果c是ChildClass对象,那么为什么它不能调用ChildClass的方法呢? 比如: 特别是: Object s=new StringBuffer(); 这里s是StringBuffer的对象,但是s.append(null)是编译时错误。为什么会这样?因为编译器不知道引用s将在运行时引用StringBuffer的实例,而Java是因为编译器不知道引用s将在运行时引用StringBuffer的实例,而Javaisc被声明为父类。因此,编译器只知道它是它的父类或某个子类。假设在某个地方重
c
是ChildClass
对象,那么为什么它不能调用ChildClass
的方法呢?
比如:
特别是:
Object s=new StringBuffer();
这里
s
是StringBuffer
的对象,但是s.append(null)
是编译时错误。为什么会这样?因为编译器不知道引用s
将在运行时引用StringBuffer
的实例,而Java
是因为编译器不知道引用s
将在运行时引用StringBuffer
的实例,而Java
isc
被声明为父类。因此,编译器只知道它是它的父类
或某个子类。假设在某个地方重新分配了另一条语句c
:
c = new SomeOtherChildClass();
这是合法的,因为SomeOtherChildClass
也是ParentClass
的子类,并且您已经告诉编译器c
可以是任何ParentClass
。现在,如果编译器看到
c.methodOfChildClass();
它如何知道c
是ChildClass
而不是SomeOtherChildClass
没有该方法
另外,如果您确定c
确实是一个ChildClass
,在某个时候,您可以通过向下转换让它调用ChildClass
方法:
((ChildClass)c).methodOfChildClass();
强制转换将使编译器将c
视为ChildClass
;在运行时,程序将检查以确保c
确实是ChildClass
,否则程序将抛出ClassCastExceptionc
声明为ParentClass
。因此,编译器只知道它是它的父类
或某个子类。假设在某个地方重新分配了另一条语句c
:
c = new SomeOtherChildClass();
这是合法的,因为SomeOtherChildClass
也是ParentClass
的子类,并且您已经告诉编译器c
可以是任何ParentClass
。现在,如果编译器看到
c.methodOfChildClass();
它如何知道c
是ChildClass
而不是SomeOtherChildClass
没有该方法
另外,如果您确定c
确实是一个ChildClass
,在某个时候,您可以通过向下转换让它调用ChildClass
方法:
((ChildClass)c).methodOfChildClass();
强制转换将使编译器将c
视为ChildClass
;在运行时,程序将检查以确保c
确实是ChildClass
,否则程序将抛出ClassCastException
,您需要强制转换对象以使用实例的方法
Object s = new StringBuffer();
StringBuffer s2 = (StringBuffer) s;
s2.append(null);
尽管是StringBuffer的一个实例,但它仍然是Object类型,并且Object没有method append您需要强制转换该对象以使用实例的方法
Object s = new StringBuffer();
StringBuffer s2 = (StringBuffer) s;
s2.append(null);
尽管是StringBuffer的一个实例,但它仍然是Object类型,并且Object没有method append编译器的工作是确保不调用任何与调用它的变量不匹配的方法。为了帮助编译器实现这一点,我们给所有变量一个“类型”。类型可以是“int”之类的基元类型,也可以是类、枚举或接口。如果是类、接口或枚举;然后,该类、接口或枚举中列出的方法就是编译器允许您在该变量上使用的方法
变量的“类型”不一定与变量引用的对象的“类”相同。在您的示例中,类型是Object
,但类是StringBuffer
。但是编译器用来检查方法调用是否正常的是类型,而不是类;因为编译器不可能知道您可能使用变量引用的每个对象的类
如果语言不是这样工作的,那么变量没有类型就没有意义了。Javascript就是这样工作的——所有东西都声明为var
,没有真正的类型系统。当我们说Java是“静态类型”时,我们的意思是我们必须给变量类型,这样做有助于编译器保护我们不滥用变量。编译器的工作是确保您不调用任何与调用它的变量不匹配的方法。为了帮助编译器实现这一点,我们给所有变量一个“类型”。类型可以是“int”之类的基元类型,也可以是类、枚举或接口。如果是类、接口或枚举;然后,该类、接口或枚举中列出的方法就是编译器允许您在该变量上使用的方法
变量的“类型”不一定与变量引用的对象的“类”相同。在您的示例中,类型是Object
,但类是StringBuffer
。但是编译器用来检查方法调用是否正常的是类型,而不是类;因为编译器不可能知道您可能使用变量引用的每个对象的类
如果语言不是这样工作的,那么变量没有类型就没有意义了。Javascript就是这样工作的——所有东西都声明为var
,没有真正的类型系统。当我们说Java是“静态类型”时,我们的意思是我们必须给变量类型,这样做有助于编译器保护我们不滥用变量。您必须将对象强制转换为stringbuffer类型,或者您必须像下面这样声明s对象stringbuffer s=new stringbuffer()然后,您可以调用此类的所有方法,您必须将对象强制转换为stringbuffer类型,或者必须声明s对象,如stringbuffer s=new stringbuffer(),然后