大数据课程体系-学习笔记-第一阶段-Java Base
来源:互联网 发布:python 矩阵乘法 编辑:程序博客网 时间:2024/05/16 17:29
- 接口和抽象类
- 简要说明
- 参考资料
- 例子对比
- 抽象类
- 接口
- 区别与联系
- 语法区别
- 设计区别
- JDK8中的新特性-default方法defender方法转载
- 简要说明
接口和抽象类
简要说明
当初在学习Java的时候,对于接口和抽象类的概念不是十分清晰,感觉二者几乎一样,没有什么本质的区别,在这个假期第二次读了《Android源码设计模式解析与实战》后,深刻认识到了抽象类和接口的重要性,在这里和大家一起梳理一下二者。
参考资料
- http://www.cnblogs.com/dolphin0520/p/3811437.html
- http://blog.csdn.net/chenssy/article/details/12858267
- http://www.importnew.com/7302.html
例子对比
- 请大家仔细对比,下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:
- 抽象类
abstract class Door { String door; //可以有默认变量 private String Name; //可以有私有变量 protected String name; //可以有保护变量 public String brand;//可以有公有变量 //可以有构造函数 public Component(String name){ this.name = name; } //可以有抽象方法 public abstract void open(); public abstract void close(); //可以有非抽象方法 public void doSomething(){ System.out.println("Open"); }}
- 接口
interface Door { String door; //只有默认变量,为 public static final 修饰 public abstract void open(); //只有抽象方法 public abstract void close();}
抽象类
- 抽象方法:一种特殊的方法:它只有声明,而没有具体的实现
- 抽象方法必须用abstract关键字进行修饰。
- 抽象类必须在类前用abstract关键字修饰。
- 如果一个类含有抽象方法,则称这个类为抽象类,
- 因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。
- 在其他方面,抽象类和普通的类并没有区别。
接口
- 要让一个类遵循某组特地的接口需要使用implements关键字,具体格式如下:
class ClassName implements Interface1,Interface2,[....]{
}一个类遵循多个特定的接口。
- 如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。
- 如果一个抽象类遵循某个接口,可以不实现该接口中的抽象方法。
区别与联系
语法区别
抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract 方法;
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
设计区别
- 抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。
- 回到上面门的例子上,将其简化
- 门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:
设计成抽像类:
abstract class Door {
public abstract void open();
public abstract void close();
}或者设计成接口:
interface Door {
public abstract void open();
public abstract void close();
}但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:
1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;
2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。
从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。
interface Alram { void alarm();}abstract class Door { void open(); void close();}class AlarmDoor extends Door implements Alarm { void oepn() { //.... } void close() { //.... } void alarm() { //.... }}
JDK8中的新特性-default方法(defender方法)(转载)
原文链接
我们都知道在Java语言的接口中只能定义方法名,而不能包含方法的具体实现代码。接口中定义的方法必须在接口的非抽象子类中实现。下面就是关于接口的一个例子:
public interface SimpleInterface { public void doSomeWork();}class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); }}
那么,如果我们在SimpleInterface里面添加一个新方法,会怎样呢?
public interface SimpleInterface { public void doSomeWork(); public void doSomeOtherWork();}
- 如果我们尝试编译上面的这段代码,会得到如下结果:
$javac .\SimpleInterface.java.\SimpleInterface.java:18: error: SimpleInterfaceImpl is not abstract and does not override abstract method doSomeOtherWork() in SimpleInterfaceclass SimpleInterfaceImpl implements SimpleInterface{^1 error
因为接口有这个语法限制,所以要直接改变/扩展接口内的方法变得非常困难。我们在尝试强化Java 8 Collections API,让其支持lambda表达式的时候,就面临了这样的挑战。为了克服这个困难,Java 8中引入了一个新的概念,叫做default方法,也可以称为Defender方法,或者虚拟扩展方法(Virtual extension methods)。Default方法是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。接下来,让我们看一个例子:
public interface SimpleInterface { public void doSomeWork(); //A default method in the interface created using "default" keyword //使用default关键字创在interface中直接创建一个default方法,该方法包含了具体的实现代码 default public void doSomeOtherWork(){ System.out.println("DoSomeOtherWork implementation in the interface"); }}class SimpleInterfaceImpl implements SimpleInterface{ @Override public void doSomeWork() { System.out.println("Do Some Work implementation in the class"); } /* 1. Not required to override to provide an implementation 2. for doSomeOtherWork. 3. 在SimpleInterfaceImpl里,不需要再去实现接口中定义的doSomeOtherWork方法 */ public static void main(String[] args) { SimpleInterfaceImpl simpObj = new SimpleInterfaceImpl(); simpObj.doSomeWork(); simpObj.doSomeOtherWork(); }}
该程序的输出是:
Do Some Work implementation in the classDoSomeOtherWork implementation in the interface
如果一个类实现了两个接口(可以看做是“多继承”),这两个接口又同时都包含了一个名字相同的default方法,那么会发生什么情况? 在这样的情况下,编译器会报错。用例子来解释一下:
public interface InterfaceWithDefaultMethod { public void someMethod(); default public void someOtherMethod(){ System.out.println("Default method implementation in the interface"); }}public interface InterfaceWithAnotherDefMethod { default public void someOtherMethod(){ System.out.println("Default method implementation in the interface"); }}
然后我们定义一个类,同时实现以上两个接口:
public class DefaultMethodSample implements InterfaceWithDefaultMethod, InterfaceWithAnotherDefMethod{ @Override public void someMethod(){ System.out.println("Some method implementation in the class"); } public static void main(String[] args) { DefaultMethodSample def1 = new DefaultMethodSample(); def1.someMethod(); def1.someOtherMethod(); } }
如果编译以上的代码,会得到一个编译器错误,因为编译器不知道应该在两个同名的default方法中选择哪一个,因此产生了二义性。
- 大数据课程体系-学习笔记-第一阶段-Java Base
- 大数据课程体系-学习笔记-第一阶段-Linux Base
- 大数据课程体系-学习笔记-第一阶段-Java IDE
- 大数据课程体系-学习笔记-第一阶段-Java Collection
- 大数据课程体系-学习笔记-第一阶段-Java Thread
- 大数据课程体系-学习笔记-第一阶段-Java Reflect
- 大数据课程体系-学习笔记-第一阶段-Java Socket(转载)
- 大数据课程体系-学习笔记概要
- java base学习笔记
- java课程体系mybaties的学习
- Java学习第一阶段
- java学习第一阶段2
- java学习第一阶段3
- java学习第一阶段4
- uboot分析第一阶段学习笔记
- u-boot 第一阶段学习笔记
- DT大数据课程第一阶段第8讲高薪笔记和作业@王家林_DT大数据梦工厂
- JAVA的课程体系是什么
- 居中+循环滚动的listview(1)
- Android Service的学习和总结
- Linux学习笔记--ln命令(链接命令)
- 判断一个字符串包含某个字符/截取指定字符窜
- 正则表达式
- 大数据课程体系-学习笔记-第一阶段-Java Base
- view 的 measure方法
- 一句Python命令启动一个Web服务器
- Hibernate的一级缓存简介
- Hadoop集群安装配置实验
- 6410 qtopia2.2.0开发:一 编译PC qtopia2.2.0
- JAVA_JCF(Java Collection Framework)学习笔记(四)
- Android中Canvas绘图基础详解(附源码下载)
- Ionic基础——侧边栏ion-side-menus 以及ion-tap结合侧边栏详解