为什么我们真的需要向下转型? [复制]

2023-11-26

我试图弄清楚为什么我需要向下转型。我重新阅读了拼贴画中的笔记,发现了下面的例子。

class Student {...}

class Graduate exteds Student {
   getResearchTopic(){...} // this method only exists in Graduate class.
}

我们有一个对 Student 类的引用,并且想要访问 getResearchTopic 方法;

Student s1 = new Graduate();
if(s1 instanceof Graduate){
   ((Graduate)s1).getResearchTopic();
}

向下转型的好例子啊?我的问题是为什么不首先宣布 s1 为毕业生?是否有一个现实生活中的例子,我必须向下转型而不是使用实际类的实例?


好吧,你可以声明引用s1属于类型Graduate。通过声明引用获得的主要好处super type,是多态性.

通过超类型引用,指向子类对象,可以将同一个引用绑定到多个子类对象。实际调用的方法将在运行时根据指向的对象决定。但是,实现这一点的主要条件是,该方法也应该在子类中定义,否则compiler将无法找到方法声明。

在这里,你被迫downcast,因为您尚未在超类中定义该方法。由于编译器无法看到该方法的定义Student班级。它不知道实际对象是什么s1指着。请记住,编译器仅检查引用类型来查找方法声明。

一般来说,每当您看到自己在代码中向下转换为子类时,这几乎总是一个错误的迹象(但也有一些例外)。你应该修改你的课程。


让我们看看使用超类引用而不是子类引用可以获得什么好处:

例如:假设你有另一个子类Student as:

class Phd extends Student {
    getResearchTopic(){...}
}

并且您还提供了一个定义(默认定义)Student class:

class Student {
    getResearchTopic(){...}
}

现在,您创建以下两个对象,它们都由Student参考:

Student student = new Phd();
student.getResearchTopic();   // Calls Phd class method

student = new Graduate();
student.getResearchTopic();    // Calls Graduate class method

因此,只需一个引用,您就可以访问特定于子类的方法。


您可以在以下位置看到此功能的一个主要实现factory method模式,其中单个静态方法根据某些条件返回不同子类的对象:

public static Student getInstance(String type) {
    if (type.equals("graduate")) 
        return new Graduate();
    else if (type.equals("phd"))
        return new Phd();
}

所以,你可以看到同一个方法返回不同子类的对象。

您可以做的所有上述事情都只是因为一个概念:

超类引用可以引用任何子类对象,但反之则不然.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我们真的需要向下转型? [复制] 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • Java EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • 当我从 Netbeans 创建 Derby 数据库时,它存储在哪里?

    当我从 netbeans 创建 Derby 数据库时 它存储在哪里 如何将它与项目的其余部分合并到一个文件夹中 右键单击Databases gt JavaDB in the Service查看并选择Properties This will

随机推荐

  • 确定.Net Core控制台应用程序是否以用户交互模式运行

    是否可以确定 Net Core 控制台应用程序是否以用户交互模式运行 在 Net 的早期版本中可以进行测试Environment UserInteractive查看用户是否有权访问该应用程序 这在 Net core中似乎不存在 NET Co
  • 获取正在运行或挂起的 PHP 脚本的堆栈跟踪

    我有一个每晚从 cron 作业运行的脚本 最近 脚本进入几分钟后就开始完全冻结 我不明白为什么 如果这是 Java 我可以简单地运行kill 3 PID它会在标准输出中打印线程转储 PHP 中是否有任何等效项 我可以在其中获取正在运行的 P
  • Java路径..jvm.cfg错误

    谁能告诉我为什么当我尝试运行 Java 程序时出现以下错误 程序编译成功 但无法运行 我已经设置了Java的路径 C JavaServ gt javac hello1 java C JavaServ gt java hello1 Error
  • mysql 存储过程与 INTO OUTFILE

    我有一个 mysql 存储过程 我想做两件事 1 查询一个表 并将结果作为正常结果集返回 2 迭代结果集并从过程本身创建一个格式化文本文件 我查看了 INTO OUTFILE 但似乎 INTO OUTFILE 将原始结果写入指定的文件 而且
  • 在更改类中的属性时,有没有办法让 didSet 工作?

    我有一个带有属性观察者的类作为属性 如果我更改该类中的某些内容 是否有办法触发 didSet 如示例所示 class Foo var items 1 2 3 4 5 var number Int 0 didSet items number
  • React Native 无限滚动

    我试图获得无限滚动的最小示例 所以我有这个 var React require react native var StyleSheet View Image ListView React var data id 1 profile pict
  • PostgreSql:禁止更新列:如何?

    使用 PostgreSql 可以在没有触发器的情况下不允许更新列 只允许插入 完全未经测试 但由于 Postgres SQL 支持列级权限 看起来可能是这样 http www postgresql org docs current stat
  • N 元组与对

    在 Ocaml 中 具有不同元数的元组具有不同的类型和值构造函数 let a 1 2 3 val a int int int 1 2 3 let b 1 2 3 val b int int int 1 2 3 请注意 第二个示例 b 比第一
  • 配置 ELMAH:无法识别的配置部分错误

    Setup 视窗XP NET框架3 5 SP1 ASP NET MVC 版本 1 我一直在尝试按照以下说明设置 ELMAHhttp code google com p elmah wiki MVC但按 F5 时出现以下错误 Descript
  • SVG 仅在 Safari 中悬停时调整大小

    我有一个奇怪的问题 svg 在 Safari 中悬停时调整大小 我使用 jquery 的悬停来用稍微不同的 svg 替换页面上的 svg 除了 Safari 之外 此功能在所有浏览器中都可以正常工作 由于某种原因 Safari 会在鼠标悬停
  • 更改密码后 KeyStore getEntry 返回 null

    您好 我有一个程序需要在密钥库中存储密钥 我生成一对密钥并签署一个值 这始终可以完美运行 当用户进入首选项并更改密码或将密码模式更改为 pin 模式时 就会出现问题 之后 当我尝试访问私钥时 密钥库返回给我一个空值 我知道密钥存储值是用解锁
  • Julia:添加包的问题 (BinDeps)

    我是 Julia 包管理器的新手 在安装 GLPK 和 LinProgGLPK 时遇到问题 我已经跑了Pkg Init 并已成功安装 Curl 使用Pkg add Curl 但是 当我尝试安装 GLPK 或 LinProgGLPK 使用Pk
  • PHP 的基本身份验证产生无限循环

    由于某种原因 我无法在我的服务器上使用 PHP 进行基本身份验证 我正在使用手册页中的确切代码
  • 如何扩展可用 Java 语言环境列表

    我正在寻找一种方法将更多区域设置添加到 Java 1 6 中可用的区域设置中 但我想要创建的区域设置没有 ISO 3166 国家 地区代码 也没有 ISO 639 语言代码 无论如何 有什么办法可以做到这一点吗 我想添加的区域设置仅在语言名
  • 递归块内的 ARC 行为

    我制作了这两个实用函数 void dispatch void f afterDelay float delay dispatch after dispatch time DISPATCH TIME NOW int64 t delay NSE
  • Appengine - 使用 https 的本地开发服务器

    目标 使用 App Engine 开发服务器缩短开发反馈周期 为了我的使用 它必须作为公共 HTTPS 地址可用 App Engine 开发服务器仅支持 HTTP 这个怎么做 使用 ngrok 将本地开发环境公开为 https 公开可用地址
  • PyLint 错误空白配置

    有没有办法配置检查bad whitespace检查 PyLint 我目前可以禁用检查 但我宁愿强制执行空白约定而不是禁用它 您可以使用两个选项 全局禁用错误空白警告 pylint disable C0326 使用 Pylint 配置文件 p
  • 为什么固定定位会改变元素的宽度?

    我有一个 div 其宽度设置为100 当我添加position fixed到它 宽度变成16px larger 我注意到身体上有8px各边都有边距 所以我猜position fixed以某种方式忽略了包含它的正文标签的边距 我看了看MDN
  • 如何创建具有可变数量参数的函数?

    如何在 Rust 中创建具有可变数量参数的函数 就像这段Java代码 void foo String args for String arg args System out println arg 一般来说 你不能 Rust 不支持可变参数
  • 为什么我们真的需要向下转型? [复制]

    这个问题在这里已经有答案了 我试图弄清楚为什么我需要向下转型 我重新阅读了拼贴画中的笔记 发现了下面的例子 class Student class Graduate exteds Student getResearchTopic this