- java向上造型的意义
- 如何理解向上造型有利于提高程序的可扩展性和简洁性
- 什么时候使用向上造型
关于上面三个问题,我之前也在网上查询过,但大多数回答都感觉要不就是套官话,要不就没说到点上。虽然向上造型使用频率不是很高,但懂了它会对我们对面向对象的理解更深。
以下为我个人见解,仅供参考
为方便大家理解,先来捋一下什么是向上造型吧
public class Person{
//定义父类Person
public void eat(){
System.out.println("person eat");
};
public void shower(){
System.out.println("person shower"); //父类独有方法
}
}
public class Man extends Person{
//子类Man继承父类
public void eat(){
System.out.println("man eat");//重写父类eat()方法
}
public void play(){
System.out.println("man play");//子类独有方法
}
}
//测试类
public class PersonTest {
public static void main(String[] args) {
Person pMan = new Man(); //向上造型
pMan.eat(); //结果为:man eat
pMan.shower(); //结果为:person shower
pMan.play(); //报错: Cannot resolve method 'drink' in 'Person'
}
}
通过代码可知,向上造型就是父类指向子类的对象。
可以看出,在实现向上造型后,实例化后的对象pMan即可调用子类重写的方法,也可以调用父类未被重写的方法,但不能调用子类独有的方法(可以继续通过向下造型实现),并且如果需要调用父类已被重写的方法,用super关键词即可。相比于分别创建父类和子类的对象再去分别调用其方法,使用向上造型可以减少代码量,提高程序的简洁性。
向上造型的意义便在此,如果你既想用父类的方法,又想特指子类的方法,向上造型后便可以通过是否重写父类的方法来实现选择调用父类还是子类的方法。
相比于分别创建父类和子类的对象再调其方法,使用向上造型可以极大提高程序的可扩展性,便于日后维护代码。那除了这样情况还有什么地方向上造型用的多呢。
接口回调
接口不可以实例化,但是可以有一个类来实现接口,实现接口的类可以继承接口的所有方法。
接口回调是用接口句柄来得到并调用实现这个接口的子类的引用,本质上和向上转型没有差别。
public interface Behavior{
public void sleep(); //定义接口需要实现的方法sleep()
}
public class Woman implements Behavior{
@Override //子类Woman继承Behavior接口并实现其方法
public void sleep() {
System.out.println("woman 实现接口方法");
}
public class Man implements Behavior{
@Override //子类Man继承Behavior接口并实现其方法
public void sleep() {
System.out.println("man 实现接口方法");
}
这两类都实现了接口的方法,但是内容可能不一致。如果现阶段需要用到接口Behavior,但是暂时不确定使用哪个子类去实现接口Behavior的方法。
那么可以创建一个方法,传入接口的“对象”进去,再调用其方法,如下:
public class DoThing {
public void doThings(Behavior human){
human.sleep(); //调用子类实现的sleep()
}
}
类DoThing用到了接口的方法,但是传参时未定义具体实例化对象,使用接口Behavior的句柄"Behavior human"来实现,再调用其sleep()方法,因其未指定哪个子类实现,所以可以根据情况后实例化子类对象再调用DoThing类的方法:
//测试类
public class PersonTest {
public static void main(String[] args) {
DoThing dt = new DoThing();
Behavior womenBehavior = new Woman(); //Woman接口回调方法
Behavior manBehavior = new Man(); //Man接口回调方法
dt.doThings(womenBehavior); //调用的是Woman对接口的实现
dt.doThings(manBehavior); //调用的是Man对接口的实现
}
}
结果:
woman 实现接口方法
Man 实现接口方法
这样使用接口调用有助于具体实现与事务处理的解耦,在类DoThing处理事务时,我们不需要知道去调用哪个子类实现接口的方法,可以在具体运行时再去根据实例化对象调用相应的实现方法,这样还方便日后扩充和维护代码。
在上述代码中,Man和Woman虽然被声明为Behavior接口类型,但在实例化过程是实现的子类,因此可以称作为接口的回调对象。
如有错误,欢迎批评指正@_@