试图从扩展类中获取超类

时间:2015-11-20 23:52:50

标签: java

尝试仅传递函数中扩展类的父类数据。

public class ParentClass {
 String pageNo;
}

public class ExtendClass extends ParentClass {
 String lineNo;
}

在另一堂课中,我试图

dosomething(...){

 savePage((ParentClass)extendClass);
}

 savePage(ParentClass pclass){
.....
}

但是当我查看函数savePage时,我仍然可以看到lineNo我不想看到的内容。

更新

我已经添加了我正面临的问题的调试图片。即使在向PageApi投降后,我仍然会看到"元素"存在于BoardPage class enter image description here

2 个答案:

答案 0 :(得分:2)

在我看来,你想要达到的目标是不可能的。

如果您创建ExtendClass的实例,则该实例始终具有lineNo字段。

当您明确转换或隐式转换ExtendedClass类型为ParentClass时,您不会以任何方式更改实际实例。在运行时,实例在所有情况下都具有lineNo字段....现在,编译器不允许savePage方法体内的代码看到或引用该字段(除非代码首先将引用转换回类型ExtendedClass),但字段< em>将会在那里。

您正在使用调试器检查实例。调试器不遵循能够显示哪些字段的规则。它看到了一切,它向你展示了一切。并且,它清楚地向您展示了现实......该领域确实在那里。

所以...有没有办法让这个领域彻底消失?或者将其隐藏在调试器中?

答案:不,不。

(警告:这与原始问题相关,可能超出了OP的理解。)

是否应该让这个领域消失?从语言设计的角度来看?

答案:不。

将此代码视为&#34;思想实验&#34;:

ExtendedClass ec = new ExtendedClass();
ec.lineNo = 42;
ParentClass pc = (ParentClass) ec;  // Actually the cast is redundant
ExtendedClass ec2 = (ExtendedClass) pc;
System.err.println("The old line no is " + ec.lineNo);
System.err.println("The new line no is " + ec2.lineNo);

如果(假设)从ExtendedClass投射到ParentClass实际上删除了一个字段,那么当您转回ExtendedClass时,字段值将不再存在。但是ec2.lineNo实际应该包含什么?它怎么可能与ec.lineNo不同...除非我们在进行类型转换时实际创建了一个全新的对象?

通过思考,如果显式或隐式类型转换创建了一个新对象,那么你就无法有效地进行多态。多态性取决于能够从其真实类型或其超类型之一的角度对给定对象进行操作。如果创建该视图实际上创建了一个新对象......它根本不起作用......除非Java是纯函数式语言;即没有突变。

简而言之,虽然可能对于少数用例来说是一个很有吸引力的想法,但这个想法从根本上将Java打破为OO语言。

答案 1 :(得分:0)

这是我上面给出的简短回答的例子

import java.lang.reflect.Field;

public class Parenting {

static public class ParentClass { String pageNo; public ParentClass() {} public ParentClass(final ParentClass pOriginal) { // copy CTOR pageNo = pOriginal.pageNo; } } static public class ExtendClass extends ParentClass { String lineNo; } public static void main(final String[] args) throws IllegalArgumentException, IllegalAccessException { final ParentClass pc = new ParentClass(); pc.pageNo = "page #7"; final ExtendClass ec = new ExtendClass(); ec.pageNo = "page#24"; ec.lineNo = "line #25"; analyze("Pure Parent", pc); analyze("Cast Parent", ec); analyze("Copy Parent", new ParentClass(ec)); } static private void analyze(final String pTitle, final ParentClass pAnalyzeObject) throws IllegalArgumentException, IllegalAccessException { System.out.println("Analyzing " + pTitle + ":"); Class<?> p = pAnalyzeObject.getClass(); while (p != Object.class) { for (final Field f : p.getDeclaredFields()) { System.out.println("\t" + p.getName() + "\t" + f.getName() + "\t\"" + f.get(pAnalyzeObject) + "\""); } p = p.getSuperclass(); } }

}