解释学生的界面

And*_*ndy 62 java interface

几年来,我是一名教学助理,负责介绍编程模块 - 一年级本科生的Java.

它大部分进展顺利,我们设法让学生很好地接受了面向对象的编程,但学生很少看到的一点是接口.

几乎我们给出的任何解释都是因为过于设计而无法用于学习,或者与初学者的位置相差甚远.我们倾向于得到的反应是"我......看",翻译为"我不明白,听起来不太有用".

这里的任何人都有成功教学生接口的方法吗?我不再是助教了,但总是唠叨我.

Ian*_*las 31

如果你试图向初学者解释它,我会坚持认为接口可以促进代码中的代码重用和模块化:

例如,假设我们要绘制一些对象:

public class Painter {
    private List<Paintable> paintableObjects;

    public Painter(){
       paintableObjects = new ArrayList<Paintable>();
    }

    public void paintAllObjects(){
        for(Paintable paintable : paintableObjects){
            paintable.paint();
        }
    }
}

public interface Paintable {
     public void paint();
}
Run Code Online (Sandbox Code Playgroud)

现在你可以向学生解释,如果没有Paintable接口,Painter对象需要有方法来绘制某些类型的对象,比如一个被调用的方法paintFences(),paintRocks()并且我们需要为Collection我们希望画家成为的每种类型的对象都有一个新的能够画画.

但幸运的是,我们有接口使绘制对象变得轻而易举,对象的绘制方式完全取决于实现Paintable接口的类.

编辑

我忘记提到的另一个好处是,如果你需要添加新对象来绘制代码库,你需要做的就是创建一个实现Paintable的新类,而Painter类永远不需要改变.从这个意义上讲,Painter类永远不会依赖于它要绘制的对象,它只需要能够绘制它们.

编辑2

James Raybould让我想起了我忘记提及的接口的关键用途:在组件之间建立一个接口,比如Paintable对象和Painter对象,可以让你更容易地与其他人一起开发.一个开发人员可以处理Painter对象,另一个可以处理Paintable对象,他们为了正常工作而必须做的就是事先定义一个他们都会使用的公共接口.我知道当我在大学水平项目中与其他人一起开展项目时,当你试图让每个人都在项目的不同部分工作并且最终所有组件都很好地结合在一起时,它真的很有帮助.

  • 但它可以 - eclipse和apache的代码约定. (2认同)

aep*_*yus 29

在向非程序员解释界面和面向对象概念时,我总是使用家庭娱乐系统类比.

DVD播放器,电视,有线电视盒,遥控器都是封装复杂和复杂功能的对象.然而,它们彼此之间以及操作它们的人类之间的接口在很大程度上隐藏了这种复杂性中的大部分.

电视插孔中的视频是由DVD播放器和有线电视盒以及许多其他类型的设备实现的接口.

我怀疑学生可以用一种教育练习来完全使用Java代码来描述他们自己的家庭娱乐系统.

  • +1:在软件中使用"接口"这个词甚至可能在历史上源于其在硬件中的使用. (2认同)

cor*_*iKa 16

"凡类的东西,典型的接口做一些事情,所以我可能有车,但我绝不会去'carring’但我可能会去驾驶...所以我的车有可能实现'可控’的界面."

编辑:

马克提出了一个很好的观点.接口根本不做任何事情,而是定义发生什么行为.而且,他还提出了一个不想让观众感到困惑的好点.并不是说可以混淆经验丰富的开发人员,但混淆一个全新的学生绝对不是一个好主意.鉴于此,我正在修改我的单行班轮.

"类定义存在的地方,接口定义行为.类定义什么是什么,而接口定义什么东西.所以我可能有一辆车,它有像引擎,它有多少气体,它是历史MPG是什么,等等,但我永远不会去"开车".另一方面,我可能会去驾驶......我的车可以驾驶吗?如果我给它一个Drive方法,它可以.我也可以有"Driveable"界面一个驱动方法,并把它留给汽车来确定驾驶真正意味着什么.现在,如果我只有汽车,那么拥有一个界面并不是什么大问题.但卡车呢?如果它们都是可驾驶的,我可以简单地拥有一个List<Drivable对于他们两个.当然,这位敏锐的学生说:"为什么汽车和卡车都不能简单地用一种抽象的Drive方法扩展车辆?" 其中,实际上是一个非常有效的概念.但是,航天飞机怎么样?Car和Truck之间很少有组件适用于航天飞机,因此它似乎不适合扩展Vehicle类.或者未来的汽车呢?我们不知道他们会是什么样的,他们可能没有机会,他们可能只是让我们四处奔走的能量泡沫,但我们仍然可以称他们的行为drive()."

吐气

现在段落/论文有点冗长,但我可以看到,有些幻灯片或黑板,对于一年级学生来说是有效的(假设他们首先理解抽象课程).

  • @supercat - 这非常令人困惑.发布的互动列表?事物的默认实现集?他们只是盯着他,就像他说希腊语一样. (2认同)

Har*_*555 11

好吧,我刚刚解释了工作伙伴的接口,她正在从进度中学习java,而且她在开始时并没有得到所有的OOP东西所以我只是从非软件工程的角度解释了一切,我对接口的解释像这样:

假设你想聘请一名管道工修理你房子里的一些东西,你不知道(而且你不在乎)你最终可能会招聘谁,但你知道管道工必须能做些什么.因此,您定义了一组任务,声称自己是水管工的人必须知道该怎么做.当然,每个人都可以有自己的方式执行每项任务,但最后,你招聘的人是水管工,因为他们知道如何完成每项任务.所以,如果你要在java中编写它,首先要做的是定义一个interface像这样的管道工:

public interface Plumber
{ //silly code here }
Run Code Online (Sandbox Code Playgroud)

那么,让我们说我知道如何完成你要求的每项任务,所以我完全符合你的要求,所以根据你我是水管工.所以,今天我决定成为你的管道工,你决定雇用我(耶!),根据最后一个例子,你可以说我是一个知道如何以特定的方式开发软件和管道的人,如果我是为我编写代码作为一个类我可以写这样的东西:

public class Rick extends Person implements SoftwareDeveloper, Plumber
Run Code Online (Sandbox Code Playgroud)

以后你可以用我作为你的水管工修理你房子里的东西:

Plumber thePlumber = rick;
thePlumber.fixLeak(myHouse.bathroom.leak) // =(
Run Code Online (Sandbox Code Playgroud)

从这一点来看,剩余的OOP概念很容易解释.


Pai*_*aiS 8

好吧,最近,我碰巧向亲近的人解释了这一点.我解释"为什么是接口?"这个问题的方式是以USB端口和USB驱动器为例.

可以将USB端口视为规范,只要它们实现了规范,任何USB驱动器都可以插入其中.所以在这种情况下,端口成为接口和众多类型的USB棒可用,成为一流.前面提到这个例子,如果我要给某人提供一个USB驱动器(类),我不需要告诉他们(调用方法)我要经过什么.如果调用方法采用USB驱动器(类类型)作为参考,我将无法通过任何只有端口所针对的USB驱动器.

总结一下,Intefaces,帮助调用者与调用方法(在调用方法需要特定类型的实例的用例中),无论您传递的是什么实例,调用者以及被调用者确保它(实例)适合接口参考(用于类比的USB端口).


mer*_*ike 7

上课时,我们花了最后几节实现quicksort.很难按姓名对人员名单进行排序.如果你不得不按年级排序这个清单,你现在会做什么?如果你不得不按年龄排序恐龙列表,你会怎么做?到目前为止,您唯一知道的方法是复制快速排序的代码,并更改比较及其操作的类型.这样做会有效 - 直到你发现那个总是困扰你的快速入口的难以捉摸的虫子,并且不得不将它分散在整个地方散布的几十个那个快速入口的副本中.

今天,我们将学习更好的方法.

我们可以编写一个快速排序,而无需定义我们要对列表进行排序的顺序,并在调用该快速排序时单独定义该顺序(并且只定义该顺序).

[插入接口和多态的机制的解释,使用Comparator接口作为示例,这里]

现在,只有一个quicksort副本,而且只需要修复一次bug.此外,人们可以在不了解它的情况下使用quicksort(或者如果他们已经理解了它,而无需在想要对其进行排序时考虑其机制).此外,编写快速排序的人不需要知道您需要对列表进行排序的顺序.因此,界面隔离了两组程序员,允许他们孤立地开发他们的软件部分.这就是为什么在许多编程语言中,你会在api中找到经过良好实现和测试的排序方法,即使这些方法的程序员不能知道所有类型的对象和人们想要在以后排序的命令.


Tho*_*sen 6

我通常使用"合同",但"承诺庄严地提供"也可能有助于理解.


JRL*_*JRL 5

我推荐Head First Design Pattern的第一章.Duck模拟解释了使用继承的问题,本章的其余部分将解释如何执行它.