很形象的接口的使用——针对初学者

里氏代换原则是什么?听起来很高深,不过我们也不是什么学院派,就不讲大道理了,直接拿个例子来说一下。
我们拿人和程序员举个例子。人是一个大类,程序员是继承自人的子类。看看这句话:人需要吃饭。这句话我们把“人”换成“程序员”,就是:程序员需要吃饭,这样换不会有什么问题。现在我们反过来,把“程序员可以用计算机写程序”里边的程序员换成“人”,就是:人可以用计算机写程序。这样就不一定正确了,否则问题可就大了,我们这些程序员只怕没得饭吃了。
这个就是里氏代换原则:使用父类的地方肯定可以用它的一个子类来替换掉,但是使用一个子类的时候用它的父类来替换就不一定正确了。
好,现在我们回到程序设计里边来。
看看下面的程序:
一个学校里边,有两种人:学生、老师。他们都要吃饭和睡觉。

public interface 人{
void 吃饭();
void 睡觉();
}

public class 学生 implements 人{
public void 吃饭(){
//去食堂吃饭
}
public void 睡觉(){
//回寝室睡觉
}
...//其他特有方法,比如泡妞、打游戏
}

public class 老师 implements 人{
public void 吃饭(){
//回家吃饭
}
public void 睡觉(){
//回家睡觉
}
...//其它特有方法,比如为生儿育女传宗接代的历史使命努力等不足为外人道的事情
}

public class 学校{
public void 开饭(人 ren){
ren.吃饭();
}

public void 放学(人 ren){
ren.睡觉();
}
}

这里就用到了里氏代换原则,"开饭()"和"放学()"的参数都是人,那么这个地方如果换成学生和老师肯定也可以。

人 a = new 学生();
学校.开饭(a);
学校.放学(a);

这样执行的结果就是学生回寝室吃饭。

人 b = new 老师();
学校.开饭(b);
学校.放学(b);

这样执行的结果就是老师回家吃饭。

为什么要这样写呢?这样写有什么好处呢?
我在开饭的时候完全可以直接调用"学生.吃饭();"、"老师.吃饭();"啊。
接着看。
有一天,学校里来了第三种人,家长。
家长既不是去寝室睡觉也不是回家睡觉,而是旅馆睡觉,既不是去食堂吃饭也不是回家吃饭,而是去下馆子。
这个时候学校这个系统该怎么处理呢?
如果原来没有定义"人"这个接口那就麻烦啦,所有用到人的地方代码都要改。
现在不一样了,我可以直接定义一个类:家长,这个类实现人这个接口就可以了。
好,看代码:

public class 家长 implements 人{
public void 吃饭(){
//下馆子
}
public void 睡觉(){
//去旅馆睡觉
}
...//其它特有方法,比如会见老师,晓之以钱,动之以利等等,不一而足
}

在调用的时候不需要修改任何代码,还和原来一样:

人 c=new 家长();
学校.开饭(c);
学校.放学(c);

轻松搞定家长的食宿问题!

这样一来学校来再多的客人都没关系啊,绝对可以应付自如,这也就是传说中的可扩展性!

不知道初学者看到这里是不是能够明白接口的作用。如果你还不明白,那么你把人这个接口去掉,自己写一个学校开饭和放学的类,然后再加一个家长这个新新人类进去,看看你的代码是什么样子的,再想一下在人口这么多的中国,万一哪天你的学校里来了成千上万个新新人类你该怎么办!

1 interface
Runner //定义接口

2 {

3         int
i=3;

4         public
void start();

5         void
run();

6         void
stop();

7 }

8 interface Eater extends
Runner //接口间可以继承

9 {

10         public
final static int j=4;

11         void
openMouth();

12         void
upAndDown();

13         void
goIn();

14 }

15 class
TT implements Eater //引用接口

16 {

17         public
void start()

18         {

19                
System.out.println("---------start()-------");

20         }

21         public
void run()

22         {

23                
System.out.println("---------run()-------");

24         }

25         public
void stop()

26         {

27                
System.out.println("---------stop()-------");

28         }

29         public
void openMouth()

30         {

31                
System.out.println("---------openMouth()-------");

32         }

33         public
void upAndDown()

34         {

35                
System.out.println("---------upAndDown()-------");

36         }

37         public
void goIn()

38         {

39                
System.out.println("---------goIn()-------");

40         }

41 }

42 public
class TestInterface

43 {

44         public
static void
main(String[] args)

45         {

46                 Runner tt=new TT();//接口的引用指向实现的对象

47                 System.out.println(tt.i);

48                 System.out.println(Runner.i);

49                 tt.start();

50                 Eater ee=new TT();

51                 System.out.println(ee.j);

52                 System.out.println(Eater.j);

53                 ee.start();

54         }

55 }

接口的应用2:

1 public class
TestInterface {
 2        
 3         public
static void
main(String[] args){
 4                
 5                 CareAnimalable c = new Worker();
 6                 //Worker
w = (Worker)c;
 7                 TestInterface t = new TestInterface();
 8                 t.t(c); //多态
 9
10                 c = new
Farmer();
11                 t.t(c);
12
13                
14        
}
15
16        
public void
t(CareAnimalable c){//尽量定义为接口或父类的引用
17                 c.feed();
18                 c.play();
19        
}
20 }
21
22
23 interface
CareAnimalable{
24        
public void
feed();
25        
public void
play();
26 }
27
28 class Worker
implements CareAnimalable{
29        

30        
public void
feed(){
31                
System.out.println("-----feed()----");
32        
}
33
34        
public void
play(){
35                
System.out.println("-----play()----");
36        
}
37 }
38
39 class Farmer
implements CareAnimalable{
40        

41        
public void
feed(){
42                
System.out.println("-----Farmer feed()----");
43        
}
44
45        
public void
play(){
46                
System.out.println("-----Farmer play()----");
47        
}
48 }

Java中类和接口的更多相关文章

  1. Java中类的加载、连接和初始化

    Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多 ...

  2. Java 中类与类之间的关系

    在java中类和类之间的关系基本上有依赖.关联.聚合.组合等 一.继承关系     继承指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功能的能力.在J ...

  3. Java中类的继承,属性和方法的四种修饰符的作用范围,final关键字,java的三大特点中的2个:封装和多态,以及多态的一个设计模式,模板方法模式(template method)

    (一)Java中的继承: 关于继承,在Java中类的继承只能是单继承,不像C+++那样灵活,可以多继承,多继承的后果就是各种关系乱套,就相当于一个孩子有2个母亲一样,社会关系的复杂,不利于程序后期的开 ...

  4. Java中类与类的关系

    在java中类和类的关系大致分三种:泛化.关联.依赖. 1. 泛化(Generalization) "XX是一个XX"关系(is a),通常使用的关键词为 extends.impl ...

  5. Java中类的继承深入剖析

    在Java开发中,我们常常用到继承这一概念,可以说继承是Java这类面向对象编程语言的基石.正是有了继承这个概念,使得我们可以创建分等级层次的类.今天小编就和大家一起来深入聊聊Java语言的继承. 在 ...

  6. Java抽象类、接口、内部类

    抽象类的概念: 1.Java中可以定义没有方法体的方法,还方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类: 2.如,shape类计算周长和面积的方法无法确定,那么就可以将这样 ...

  7. java 中类为啥要序列化

    java里为什么要序列化?http://zhidao.baidu.com/link?url=7_wAQ8eAl28vcJPE5OKM5Y0Bo4aINNQokHhRmI9XPszEoTO5QF-gNb ...

  8. 【转】java通用URL接口地址调用方式GET和POST方式

    java通用URL接口地址调用方式GET和POST方式,包括建立请求和设置请求头部信息等等......... import java.io.ByteArrayOutputStream; import ...

  9. Java继承和接口

    接口最关键的作用,也是使用接口最重要的一个原因:能上溯造型至多个基础类.使用接口的第二个原因与使用抽象基础类的原因是一样的:防止客户程序员制作这个类的一个对象,以及规定它仅仅是一个接口.这样便带来了一 ...

随机推荐

  1. JS 验证码的实现

    转自:https://github.com/ace0109/verifyCode 正要做一个验证码,网上找到这个还不错: gVerify.js: !(function(window, document ...

  2. 【视频点播最佳实践】使用OSS SDK上传视频到点播

    摘要: 场景 点播上传SDK缺乏需要的语言版本(如C/C++.Go等)或相应的功能(如网络流上传.追加上传),可以直接使用OSS的SDK进行上传. 准备工作 确认已开通点播服务并完成了相关配置.确认已 ...

  3. Java内存区域笔记(一)

    程序计数器: 程序计数器是一块较小的内存空间,它可以看作当前线程所执行的字节码的行号指示器. 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令. 由于Java虚拟机的多线程 ...

  4. springCloud——Eureka、Ribbon理解

    一. 服务注册中心.服务提供者.服务消费者 如何通信? 客户端: 应用主类中配置@EnableDiscoveryClient application.properties中配置defaultZone指 ...

  5. mybatis——mybatis打印sql 接口工作原理

    https://blog.csdn.net/Lxinccode/article/details/79218566 接口工作原理: Dao接口即Mapper接口.接口的全限名,就是映射文件中的names ...

  6. less中的for循环

    .loop(@count) when (@counter > 0) {   .loop((@counter - 1));    // 递归调用自身   width: (10px * @count ...

  7. Mybatis-Plus和Mybatis的区别

    1.List item 区别一如果Mybatis Plus是扳手,那Mybatis Generator就是生产扳手的工厂.通俗来讲——MyBatis:一种操作数据库的框架,提供一种Mapper类,支持 ...

  8. Kotlin使用率达35%,Java要退位了?

    在今年的Google I/O大会上,关于Kotlin,Google只说了只言片语: 在过去一年里,有35%的专业Android开发者在使用Kotlin,其中95%的开发者都对Kotlin非常满意. 之 ...

  9. python Tkinter 组件

    Tkinter的提供各种控件,如按钮,标签和文本框,一个GUI应用程序中使用.这些控件通常被称为控件或者部件. 目前有15种Tkinter的部件.我们提出这些部件以及一个简短的介绍,在下面的表: 控件 ...

  10. Bootstap

    Bootstrap框架 Bootstrap框架 Bootstrap介绍 Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架. 它是为实现快速开发Web应用程序 ...