接口回调是指:能够把使用实现了某一接口的类建立的对象的引用赋给该接口声明的接口变量,那么该接口变量就能够调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调。看下面示例。
interface People {
void peopleList();
}
class Student implements People {
publicvoid peopleList() {
System.out.println("I’m a student.");
}
}
class Teacher implements People {
publicvoid peopleList() {
System.out.println("I’m a teacher.");
}
}
publicclass Example {
publicstaticvoid main(String args[]) {
People a; // 声明接口变量
a = new Student(); // 实例化,接口变量中存放对象的引用
a.peopleList(); // 接口回调
a = new Teacher(); // 实例化,接口变量中存放对象的引用
a.peopleList(); // 接口回调
}
} java
I’m a student.
I’m a teacher.
再来看看向上转型(upcasting)的概念。编程
Shape s=new Circle(); 安全
这里,建立了一个Circle对象,并把获得的引用当即赋值给Shape。经过继承,Circle就是一种Shape。
假设你调用基类方法(它已在导出类中被覆盖):
s.draw(); ide
因为后期绑定(多态),将会正确调用Circle.draw()方法。spa
在java里面,关于跨类引用,有两条规则应该记住:
1)若是a是类A的一个引用,那么,a能够指向类A的一个实例。或者说指向类A的一个子类,这是向上转型的情形。
2)若是a是接口A的一个引用,那么,a必须指向实现了接口A的一个类的实例。这是接口回调的情形。
在java里面,向上转型是自动进行的,可是向下转型却不是,对象
须要咱们本身定义强制进行.
class B extends A{}
publicclass A {
publicstaticvoid main(String[] argts){
A a1=new A();
A a2=new B();//Upcasting向上转型
B b1=new B();
B b2=(B) new A();//DownCasting向下转型,[注意]:此处(B)进行了强制转换!
}
} 继承
从实现了某接口的对象,获得对此接口的引用,与向上转型为这个对象的基类,实质上效果是同样的。这些对象均可以调用基类型提供的方法,对于接口来讲就是回调接口中的方法,对于父类来讲就是调用父类的方法。固然在向上转型的状况下,还牵涉到子类重写(Override)父类方法的情形。接口
转型是在继承的基础上而言的,继承是面向对象语言中,代码复用的一种机制,经过继承,子类能够复用父类的功能,若是父类不能知足当前子类的需求,则子类能够重写父类中的方法来加以扩展。io
向上转型:子类引用的对象转换为父类类型称为向上转型。通俗地说就是是将子类对象转为父类对象。此处父类对象能够是接口编译
向下转型:父类引用的对象转换为子类类型称为向下转型。
前者是一个向上转型,Animal dog 引用指向new Dog();子类对象当成父类对象,只能调用父类的成员,若是子类重写了父类的方法就根据这个引用指向调用子类重写的这个方法(这个方法就是覆盖override)。这个调用过程就称为“动态绑定”。
转型须要注意的问题:
向上转型时,父类指向子类引用对象会遗失除与父类对象共有的其余方法,也就是在转型过程当中,子类的新有的方法都会遗失掉,在编译时,系统会提供找不到方法的错误。实例以下:
public class Animal {
public void eat(){
System.out.println("animal eatting...");
}
}
class Bird extends Animal{
public void eat(){
System.out.println("bird eatting...");
}
public void fly(){
System.out.println("bird flying...");
}
}
class Main{
public static void main(String[] args) {
Animal b=new Bird(); //向上转型
b.eat();
b.fly(); //此处提示在Animal中没有定义fly方法。
}
在向下转型过程当中,分为两种状况:
状况一:若是父类引用的对象若是引用的是指向的子类对象,那么在向下转型的过程当中是安全的。也就是编译是不会出错误的。
状况二:若是父类引用的对象是父类自己,那么在向下转型的过程当中是不安全的,编译不会出错,可是运行时会出现java.lang.ClassCastException错误。它可使用instanceof来避免出错此类错误。实例以下:
public class Girl {
public void smile(){
System.out.println("girl smile()...");
}
}
class MMGirl extends Girl{
@Override
public void smile() {
System.out.println("MMirl smile sounds sweet...");
}
public void c(){
System.out.println("MMirl c()...");
}
}
class main{
public static void main(String[] args) {
Girl g1=new MMGirl(); //向上转型
g1.smile();
MMGirl mmg=(MMGirl)g1; //向下转型,编译和运行皆不会出错
mmg.smile();
mmg.c();
Girl g2=new Girl();
//MMGirl mmg1=(MMGirl)g2; //不安全的向下转型,编译无错但会运行会出错
//mmg1.smile();
//mmg1.c();
if(g2 instanceof MMGirl){
MMGirl mmg1=(MMGirl)g2;
mmg1.smile();
mmg1.c();
}
}
总结:
一、父类引用能够指向子类对象,子类引用不能指向父类对象。
二、把子类对象直接赋给父类引用叫upcasting向上转型,向上转型不用强制转型。
如Father father = new Son();
三、把指向子类对象的父类引用赋给子类引用叫向下转型(downcasting),要强制转型。
如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son =(Son)father;
其中father前面的(Son)必须添加,进行强制转换。
四、upcasting 会丢失子类特有的方法,可是子类overriding 父类的方法,子类方法有效
五、向上转型的做用,减小重复代码,父类为参数,调有时用子类做为参数,就是利用了向上转型。这样使代码变得简洁。体现了JAVA的抽象编程思想。