Java 试图从扩展类中获取超类

Java 试图从扩展类中获取超类,java,Java,试图在函数中仅传递扩展类的父类数据 public class ParentClass { String pageNo; } public class ExtendClass extends ParentClass { String lineNo; } 在另一节课上,我试着 dosomething(...){ savePage((ParentClass)extendClass); } savePage(ParentClass pclass){ ..... } 但是当我查看函数sa

试图在函数中仅传递扩展类的父类数据

public class ParentClass {
 String pageNo;
}

public class ExtendClass extends ParentClass {
 String lineNo;
}
在另一节课上,我试着

dosomething(...){

 savePage((ParentClass)extendClass);
}

 savePage(ParentClass pclass){
.....
}
但是当我查看函数
savePage
参数时,仍然可以看到
lineNo
,这是我不想看到的

更新

我已经添加了我所面临问题的调试图片。即使向下转换到
PageApi
,我仍然可以看到
BoardPage类中存在的“元素”

在我看来,你试图实现的目标是不可能的

如果创建
扩展类的实例
,则该实例始终具有
lineNo
字段

当您显式地强制转换或隐式地将类型
ExtendedClass
转换为
ParentClass
时,您不会以任何方式更改实际实例。在运行时,实例具有
lineNo
字段。。。在所有情况下。现在,编译器不会让
savePage
方法体中的代码看到或引用该字段(除非代码首先将引用转换回类型
ExtendedClass
),但该字段仍然存在

您正在使用调试器检查实例。调试器不遵循哪些字段应该可见的规则。它看到了一切,也向你展示了一切。而且,它清楚地向你展示了现实。。。这个领域真的在那里

所以。。。有没有办法让这个领域完全消失?或者对调试器隐藏它

回答:没有,也没有


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

有没有办法让这片土地消失?从语言设计的角度

回答:没有

将此代码视为“思维实验”:

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

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


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

这是我上面给出的简短答案的示例

导入java.lang.reflect.Field

公共教育{

静态公共类父类{
字符串pageNo;
公共父类(){}
公共父类(最终父类原始){//copy
pageNo=pOriginal.pageNo;
}
}
静态公共类扩展类扩展父类{
字符串行号;
}
公共静态void main(最终字符串[]args)抛出IllegalArgumentException、IllegalAccessException{
最终父类pc=新父类();
pc.pageNo=“第7页”;
最终引伸类ec=新引伸类();
ec.pageNo=“第24页”;
ec.lineNo=“第25行”;
分析(“纯父母”,pc);
分析(“铸造母材”,ec);
分析(“复制父对象”,新父类(ec));
}
静态私有void analyze(最终字符串pTitle,最终父类pAnalyzeObject)抛出IllegalArgumentException,IllegalAccessException{
System.out.println(“分析“+pTitle+”:”);
类p=pAnalyzeObject.getClass();
while(p!=Object.class){
for(最终字段f:p.getDeclaredFields()){
System.out.println(“\t”+p.getName()+“\t”+f.getName()+“\t\”“+f.get(pAnalyzeObject)+”);
}
p=p.getSuperclass();
}
}

}

我不明白。强制转换不会修改对象。savePage的方法签名是什么?假设我正在尝试在savePage方法中转换为字符串或JSON,其中仍然有我想要避免的“lineNo”。请发布一个。我自己做了一些测试,无法重现您的问题。对我来说,属性
lineNo
savePage(ParentClass)
中不可见。您必须区分运行时和编译/开发时。当然,即使将对象从
ChildClass
向上投射到
ParentClass
,在
ChildClass
中定义的属性仍然存在(在运行时)。但是如果引用< <代码> ChildClass <代码>对象,使用<代码> ParentClass <代码>引用,您将无法访问<代码> ChildClass <代码> ES(在编译/开发时)的特殊方法或属性。C++:在C++中,更一般类型的转换实际上可以删除字段,然后回溯到更具体的类型是未定义的行为。这被调用,并且实际上只有当您通过值传递对象时才起作用(与传递引用或指向它们的指针相反)。就我个人而言,这是一个可怕的C++错误特性。像Java这样具有“引用类型”概念的语言完全避免了这个问题。在C++中,它也可以用一个本地的CAST来自动存储一个对象,因为这也是“在C++中创建一个新的对象”。
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);

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();
    }
}