Java基础之interface && 多态总结
1. /**
2. * 功能:接口
3. * 接口和继承的区别在于前者不能有方法体,后者可以有。
4. */
5. package com.testInterface;
6.
7. public class Test {
8.
9. /**
10. * @param args
11. */
12. public static void main(String[] args) {
13. // TODO Auto-generated method stub
14. Computer com = new Computer();
15. com.useUsb(new Cammera());
16. com.useUsb(new Phone());
17. }
18.
19. }
20.
21. //usb接口
22. interface Usb extends Usb_father{
23. //声明两个方法
24. //开始工作
25. public void start();
26. //停止工作
27. public void stop();
28. }
29.
30. //编写相机类,实现Usb接口
31. //当一个类实现了一个接口,要求该类把这个接口所有方法都实现
32. class Cammera implements Usb {
33. public void start() {
34. System.out.println("我是相机,开始工作");
35. }
36.
37. public void stop() {
38. System.out.println("我是相机,停止工作");
39. }
40.
41. @Override
42. public void father() {
43. // TODO Auto-generated method stub
44. System.out.println("Cammera类中对Usb父类接口的方法实现");
45. }
46. }
47.
48.
49. //编写手机
50. class Phone implements Usb {
51.
52. @Override
53. public void start() {
54. // TODO Auto-generated method stub
55. System.out.println("我是手机,开始工作");
56. }
57.
58. @Override
59. public void stop() {
60. // TODO Auto-generated method stub
61. System.out.println("我是手机,停止工作");
62. }
63.
64. @Override
65. public void father() {
66. // TODO Auto-generated method stub
67. System.out.println("Phone类中对Usb父类接口的方法实现");
68. }
69.
70. }
71.
72. //计算机
73. class Computer {
74.
75. //开始使用usb接口
76. public void useUsb(Usb usb) {
77. usb.start();
78. usb.stop();
79. usb.father();
80. }
81. }
82. //usb接口继承该接口
83. interface Usb_father {
84.
85. static public int a =1; //该变量必须是静态变量,private修饰符会报错
86. public void father(); //无方法体
87. }
代码2:
1. /**
2. *java三大特征之一(继承,封装,多态)
3. *多态:一种类型的多种状态
4. */
5. package com.abstract_interface;
6.
7. //汽车接口
8. interface Car {
9. //汽车名称
10. String getName();
11.
12. //获得汽车售价
13. int getPrice();
14.
15. }
16.
17. //宝马
18. class BMW implements Car {
19.
20. @Override
21. public String getName() {
22. // TODO Auto-generated method stub
23. return "BMW";
24. }
25.
26. @Override
27. public int getPrice() {
28. // TODO Auto-generated method stub
29. return 300000;
30. }
31.
32.
33. }
34.
35. //奇瑞QQ
36. class CheryQQ implements Car {
37.
38. @Override
39. public String getName() {
40. // TODO Auto-generated method stub
41. return "cheryQQ";
42. }
43.
44. @Override
45. public int getPrice() {
46. // TODO Auto-generated method stub
47. return 20000;
48. }
49.
50. }
51.
52. //汽车出售店
53. public class CarShop {
54.
55. /**
56. * @param args
57. */
58. //售车收入
59. private int money = 0;
60.
61. //卖出一部车,Car接口写到变量中,会根据实现的类进入到相应的方法中
62. public void sellCar(Car car) {
63. System.out.println("车型:" + car.getName() + " 单价:" + car.getPrice());
64.
65. //增加卖出车售价
66. money +=car.getPrice();
67. }
68.
69. //售车总收入
70. public int getMoney() {
71. return money;
72. }
73. public static void main(String[] args) {
74. // TODO Auto-generated method stub
75. CarShop aShop = new CarShop();
76.
77. //卖出一辆宝马
78. aShop.sellCar(new BMW());
79.
80. //卖出一辆奇瑞QQ
81. aShop.sellCar(new CheryQQ());
82. System.out.println("总收入:" + aShop.getMoney());
83. }
84.
85. }
继承是多态得以实现的基础。
根据以上代码分析,多态就是一种类型(都是Car类型)表现出多种状态(宝马汽车的名称是BMW,售价300000;奇瑞汽车名称是CheryQQ,售价是20000)。将一个方法调用这个方法所属的主体(对象或类)关联起来叫做绑定,分前期绑定和 后期绑定。
前期绑定:在程序运行之前进行绑定,由编译器和连接程序实现,又叫做静态绑定。并入static 方法和final 方法,注意,这里也包括private 方法,因为它是隐式final 的。
后期绑定:在运行时根据对象的类型进行绑定,由方法调用机制实现,又叫动态绑定[1],或运行时绑定。除了前期绑定外的所有方法都属于后期绑定。
多态就是在后期绑定的基础上实现的,多态能够消除类中的耦合关系,使程序更容易扩展;如上例,新增加一款汽车,则可以新增一个实现Car接口的类并实现它的所有方法,而无需对原有代码作任何修改,ShopCar类的sellCar(Car car)方法就可以处理新的车型了。
1. //桑塔纳
2. class Santana implements Car {
3.
4. @Override
5. public String getName() {
6. // TODO Auto-generated method stub
7. return "Santana";
8. }
9.
10. @Override
11. public int getPrice() {
12. // TODO Auto-generated method stub
13. return 100000;
14. }
15.
16.
17. }
以上三段代码来自韩顺平Java学习视频中,可使用Eclipse或MyEclipse运行。
接口:
1、接口不能被实例化。
2、接口所有方法都不能有方法主体。
3、一个类可以实现多个接口。
4、接口中可有变量,但必须是static修饰符修饰,并且不能使用private修饰。
5、接口可以继承接口,实现该接口的类要把继承的接口的所有方法都实现。
小结:接口是更加抽象的抽象类,抽象类里的方法可以有方法体,接口中所有的方法都不能有方法体,接口体现了程序设计多态和高内聚低耦合的设计思想。
备注:[1]摘自Java语言程序设计基础篇:动态绑定机制如下:假设对象o是类C1,C2,…,Cn-1,Cn的实例,其中C1是C2的子类,C2是C3的子类,…,Cn-1是Cn的子类,也就是说Cn是最一般的类,C1是最特殊的类。在Java中,Cn是Object类。如果对象o调用一个方法p,Java虚拟机依次在类C1,C2,…,Cn-1,Cn中查找方法p的实现,直到找到为止。一旦找到一个实现,停止查找并调用这个第一次找到的实现。
例子:
1. /**
2. * @(#)PolymorphismDemo.java
3. *
4. * PolymorphismDemo application
5. *
6. * @author
7. * @version 1.00 2013/6/3
8. */
9.
10. public class PolymorphismDemo {
11.
12. public static void main(String[] args) {
13.
14. // TODO, add your application code
15. m(new GraduateStudent());
16. m(new Student());
17. m(new Person());
18. m(new Object());
19. }
20.
21. public static void m(Object x) {
22. System.out.println(x.toString());
23. }
24. }
25.
26. class GraduateStudent extends Student {
27.
28. }
29.
30. class Student extends Person {
31. public String toString() {
32. return "Student";
33. }
34. }
35.
36. class Person extends Object {
37. public String toString() {
38. return "Person";
39. }
40. }
41.
输出:
- Student
- Student
- Person
- java.lang.Object@61de33
接口回调
接口回调:可以把实现某一个接口的类创建的对象的引用赋给该接口声明的接口变量中。那么该接口变量就可以调用被类实现的接口中的方法。那么该接口变量就可以调用被类实现的接口中的方法。实际上,当接口变量被类实现的接口中的方法时,就是通知相应的对象调用接口的方法。
showMessage.java文件
1. /**
2. * @author zone
3. *
4. */
5. interface showMessage {
6. void 显示商标(String s);
7. }
TV.java文件
1. /**
2. * @author zone
3. *
4. */
5. class TV implements showMessage {
6.
7. /* (non-Javadoc)
8. * @see showMessage#显示商标(java.lang.String)
9. */
10. @Override
11. public void 显示商标(String s) {
12. // TODO Auto-generated method stub
13. System.out.println(s);
14. }
15.
16. }
PC.java文件
1. /**
2. * @author zone
3. *
4. */
5. class PC implements showMessage {
6.
7. /* (non-Javadoc)
8. * @see showMessage#显示商标(java.lang.String)
9. */
10. @Override
11. public void 显示商标(String s) {
12. // TODO Auto-generated method stub
13. System.out.println(s);
14. }
15.
16. }
Example4_27.java文件
1. /**
2. * @author zone
3. *
4. */
5. public class Example4_27 {
6.
7. /**
8. * @param args
9. */
10. public static void main(String[] args) {
11. // TODO Auto-generated method stub
12. showMessage sm; //声明接口变量
13. sm = new TV(); //接口变量中存放对象的引用
14. sm.显示商标("长城牌电视机"); //接口回调
15. sm = new PC();
16. sm.显示商标("联想奔月5008pc"); //接口回调
17. }
18.
19. }
输出:
长城牌电视机
联想奔月5008pc
另一个例子:
例子4.28
接口Computerable.java文件
1. /**
2. * @author zone
3. *
4. */
5. interface Computerable {
6. public double 求面积();
7. }
梯形.java文件
1. /**
2. * @author zone
3. *
4. */
5. class 梯形 implements Computerable{
6.
7. double a,b,h;
8. 梯形(double a,double b,double h) {
9. this.a=a;
10. this.b=b;
11. this.h=h;
12. }
13.
14. @Override
15. public double 求面积() {
16. // TODO Auto-generated method stub
17. return ((1/2.0)*(a+b)*h);
18. }
19.
20. }
圆形.java文件
1. /**
2. * @author zone
3. *
4. */
5. class 圆形 implements Computerable {
6.
7. /* (non-Javadoc)
8. * @see Computerable#求面积()
9. */
10.
11. double r;
12. 圆形(double r){
13. this.r=r;
14. }
15.
16. @Override
17. public double 求面积() {
18. // TODO Auto-generated method stub
19. return (3.14*r*r);
20. }
21.
22. }
堆.java文件
1. /**
2. * @author zone
3. *
4. */
5. class 堆 {
6.
7. /* (non-Javadoc)
8. * @see Computerable#求面积()
9. */
10.
11. Computerable 底; //声明一个接口变量,可以回调“求面积”方法
12. double 高;
13. 堆(Computerable 底,double 高){
14. this.底=底;
15. this.高=高;
16. }
17.
18. void 换底(Computerable 底){
19. this.底=底;
20. }
21.
22. public double 求体积(){
23. return (底.求面积()*高);
24. }
25. }
Example4_28.java文件
1. /**
2. * @author zone
3. *
4. */
5. public class Example4_28 {
6.
7. /**
8. * @param args
9. */
10. public static void main(String[] args) {
11. // TODO Auto-generated method stub
12. 堆 zui;
13. Computerable bottom;
14. bottom=new 梯形(2.0,7.0,10.7); //接口变量中存放对象的引用
15. System.out.println("梯形的面积"+bottom.求面积()); //bottom接口回调求面积
16. zui=new 堆(bottom,30);
17. System.out.println("梯形底的堆的体积"+zui.求体积());
18. bottom=new 圆形(10); //接口变量中存放对象的引用
19. System.out.println("半径是10的圆的面积"+bottom.求面积());
20. zui.换底(bottom);
21. System.out.println("圆形底的堆的体积"+zui.求体积());
22. }
23.
24. }
输出:
- 梯形的面积48.15
- 梯形底的堆的体积1444.5
- 半径是10的圆的面积314.0
- 圆形底的堆的体积9420.0
接口做参数
例子4.29
接口SpeakHello.java文件
1. /**
2. * @author zone
3. *
4. */
5. interface SpeakHello {
6. void speakHello();
7. }
Chinese.java文件
1. /**
2. * @author zone
3. *
4. */
5. class Chinese implements SpeakHello {
6.
7. /* (non-Javadoc)
8. * @see SpeakHello#speakHello()
9. */
10. @Override
11. public void speakHello() {
12. // TODO Auto-generated method stub
13. System.out.println("中国人喜欢问候语:你好,吃饭了吗?");
14. }
15.
16. }
English.java文件
/**
1. * @author zone
2. *
3. */
4. class English implements SpeakHello {
5.
6. /* (non-Javadoc)
7. * @see SpeakHello#speakHello()
8. */
9. @Override
10. public void speakHello() {
11. // TODO Auto-generated method stub
12. System.out.println("英国人习惯问候语:你好,天气不错啊");
13. }
14.
15. }
KindHello.java文件
1. /**
2. * @author zone
3. *
4. */
5. class KindHello {
6. public void lookHello(SpeakHello hello) { //接口类型参数
7. hello.speakHello(); //接口回调
8. }
9. }
Example4_29.java文件
1. /**
2. * @author zone
3. *
4. */
5. public class Example4_29 {
6.
7. /**
8. * @param args
9. */
10. public static void main(String[] args) {
11. // TODO Auto-generated method stub
12. KindHello kindHello=new KindHello();
13. kindHello.lookHello(new Chinese());
14. kindHello.lookHello(new English());
15. }
16.
17. }
输出:
- 中国人喜欢问候语:你好,吃饭了吗?
- 英国人习惯问候语:你好,天气不错啊