额。。。上回书说到了多态,我们还是以代码来描述多态
上~代~码~
先放两个接口:
public interface Teacher {
public int teachType();
public void teaching();
}
public interface Student {
public void study();
}
显而易见,只要上一篇里的Person类实现了这两个接口的其中一个,那么Person就变成了老师或者学生,但是Person类要是实现了这其中一个接口,就表明了Person只可以是老师或者学生,这显然不符合人类社会的常识,毕竟职业有很多,不是只有这两种。所以。。。就要上他的派生类:
public class ChineseTeacher extends Person implements Teacher {
public void teaching() {
System.out.println("教语文");
}
public int teachType() {
return 0;
}
}
public class MathTeacher extends Person implements Teacher {
public void teaching() {
System.out.println("教数学");
}
public int teachType() {
return 1;
}
}
一旦这样定义了就会产生一个很有意思的事情,语文老师和数学老师完全是两个不一样的类啊,但是在有的方法里我也不知道参数要调用哪个类实例化的对象,就像下面的代码中的study方法:
public class Junior extends Person implements Student {
private Person mother;
private Person father;
/**
* 现在可以看到有两个方法都叫study,一个带参数一个不带参数。
* 显然这两个方法得到的结果是不一样的。
* 这个不一样我们在编译的时候就已经知道了
* 所以这就是传说中的静态多态,也就是所谓的静态绑定。
* 这同时也就是传说中的方法重载,重载的是哪个咧?当然是带参数的那个
* 因为不含参的已经在Student接口里声明过了
*/
public void study() {
System.out.println("学初中生要学的");
}
/**
* 那么study方法要完成的任务是语文老师来了就学语文,数学老师来了就学数学
* 这样就解释了多态,对于同一个方法,传进了不同的参数就会得到不同的结果,
* 但是参数的类型必须一致,所以就用Teacher接口作为参数
* 为什么不是Person呢?
* 很简单,弱智也可以继承Person类,如果传进来的参数是弱智,呵呵呵
* 因为study方法适用的参数必须是老师,
* 相当于Teacher这个接口对这个Person的派生类提供了证明,
* 不可以是工程师,也不可以是军人
* 这样在最后程序运行的时候才知道传进参数的具体类型的方式就叫动态多态。
* 同样下面的set方法其实也是动态多态
* 因为你的父母也可能是老师也可能是工程师,所以那个参数也写成Person
*/
public void study(Teacher t) {
if(t.teachType() == 0) System.out.println("学语文");
else System.out.println("学数学");
}
public Person getMother() {
return mother;
}
public void setMother(Person mother) {
this.mother = mother;
}
public Person getFather() {
return father;
}
public void setFather(Person father) {
this.father = father;
}
}
同样从这里就看出Java为什么要使用接口了,因为Java只支持单继承。接口的出现很好的解决了上述问题。
啥也不说上测试:
import java.util.Scanner;
public class TestCase {
public static void main(String[] args) {
Junior junior = new Junior();
Scanner sc = new Scanner(System.in);
System.out.println("Input lesson:(chinese,math,unknown)");
String lesson = sc.nextLine();
if("chinese".equals(lesson))
junior.study(new ChineseTeacher());
else if("math".equals(lesson))
junior.study(new MathTeacher());
else
junior.study();
sc.close();
}
}
这样随着你输入不同的课程名字去模拟动态的运行程序,就会得到不同的答案。
这样动态就算也说完了。需要注意的是方法重载,关于方法重写和方法重载之后还是会写博客说,现在就不扯那么多了
ok~