我想弄清楚为什么我需要向下转换.我从拼贴中重读了我的笔记并找到了下面的例子.
class Student {...}
class Graduate exteds Student {
getResearchTopic(){...} // this method only exists in Graduate class.
}
Run Code Online (Sandbox Code Playgroud)
我们有一个ref类到Student类,想要访问getResearchTopic方法;
Student s1 = new Graduate();
if(s1 instanceof Graduate){
((Graduate)s1).getResearchTopic();
}
Run Code Online (Sandbox Code Playgroud)
向下倾斜的好例子哈?我的问题是为什么不首先宣布s1为毕业生?是否有一个真实的例子,我将不得不转发而不是使用实际类的实例?
假设您有一个将a Student作为参数的方法.它所做的大多数事情对所有学生来说都是通用的.但如果它是一个Graduate,它也可能有其他东西.在这种情况下,您需要确定Student传入的实际是否为a Graduate并在该实例中执行某些特殊逻辑.
也许是这样的:
class StudentDAO {
public void SaveStudent(Student s) {
// Do something to save the student data to a database.
if ( s instanceof Graduate ) {
// Save their research topic too.
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,做这种事情通常是一种糟糕的编程习惯,但有时它是有道理的.
好吧,你可以声明引用s1是类型的Graduate.通过声明引用获得的主要好处super type是多态的力量.
使用指向子类对象的超类型引用,可以将相同的引用绑定到多个子类对象.并且将根据所指向的对象在运行时决定调用的实际方法.但是,这个的主要条件是,该方法也应该在子类中定义,否则编译器将无法找到方法声明.
在这里,你被迫downcast,因为你没有在超类中定义方法.由于编译器无法在Student类中看到该方法的定义.它不知道实际对象s1指向的是什么.请记住,编译器仅检查引用类型以查找meethod声明.
通常,每当您看到自己向代码中的子类转发时,它几乎总是一个错误的标志(尽管有一些例外).你应该修改你的课程.
让我们看看使用超类引用而不是子类引用可以获得什么好处:
例如:假设您有另一个子类Student:
class Phd extends Student {
getResearchTopic(){...}
}
Run Code Online (Sandbox Code Playgroud)
并且您还在类中提供了一个定义(默认值)Student:
class Student {
getResearchTopic(){...}
}
Run Code Online (Sandbox Code Playgroud)
现在,您创建以下两个对象,两者都通过Student引用指向:
Student student = new Phd();
student.getResearchTopic(); // Calls Phd class method
student = new Graduate();
student.getResearchTopic(); // Calls Graduate class method
Run Code Online (Sandbox Code Playgroud)
因此,只需一个引用,您就可以访问特定于子类的方法.
您可以在factory method模式中看到此功能的一个主要实现,其中单个静态方法根据某些条件返回不同子类的对象:
public static Student getInstance(String type) {
if (type.equals("graduate"))
return new Graduate();
else if (type.equals("phd"))
return new Phd();
}
Run Code Online (Sandbox Code Playgroud)
因此,您可以看到相同的方法返回不同子类的对象.
以上所有的东西你只能因为一个概念而做:
超类引用可以引用任何子类对象,但反之亦然.
| 归档时间: |
|
| 查看次数: |
7866 次 |
| 最近记录: |