大数据课程体系-学习笔记-第一阶段-Java Base
2016-02-17 17:02
681 查看
接口和抽象类
简要说明
参考资料
例子对比
抽象类
接口
区别与联系
语法区别
设计区别
JDK8中的新特性-default方法defender方法转载
/article/1384930.html
http://www.importnew.com/7302.html
抽象类
接口
抽象方法必须用abstract关键字进行修饰。
抽象类必须在类前用abstract关键字修饰。
如果一个类含有抽象方法,则称这个类为抽象类,
因为抽象类中含有无具体实现的方法,所以不能用抽象类创建对象。
在其他方面,抽象类和普通的类并没有区别。
一个类遵循多个特定的接口。
如果一个非抽象类遵循了某个接口,就必须实现该接口中的所有方法。
如果一个抽象类遵循某个接口,可以不实现该接口中的抽象方法。
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的;
接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法;
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
回到上面门的例子上,将其简化
门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:
设计成抽像类:
或者设计成接口:
但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:
1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;
2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。
从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。
我们都知道在Java语言的接口中只能定义方法名,而不能包含方法的具体实现代码。接口中定义的方法必须在接口的非抽象子类中实现。下面就是关于接口的一个例子:
那么,如果我们在SimpleInterface里面添加一个新方法,会怎样呢?
如果我们尝试编译上面的这段代码,会得到如下结果:
因为接口有这个语法限制,所以要直接改变/扩展接口内的方法变得非常困难。我们在尝试强化Java 8 Collections API,让其支持lambda表达式的时候,就面临了这样的挑战。为了克服这个困难,Java 8中引入了一个新的概念,叫做default方法,也可以称为Defender方法,或者虚拟扩展方法(Virtual extension methods)。Default方法是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。接下来,让我们看一个例子:
该程序的输出是:
如果一个类实现了两个接口(可以看做是“多继承”),这两个接口又同时都包含了一个名字相同的default方法,那么会发生什么情况? 在这样的情况下,编译器会报错。用例子来解释一下:
然后我们定义一个类,同时实现以上两个接口:
如果编译以上的代码,会得到一个编译器错误,因为编译器不知道应该在两个同名的default方法中选择哪一个,因此产生了二义性。
简要说明
参考资料
例子对比
抽象类
接口
区别与联系
语法区别
设计区别
JDK8中的新特性-default方法defender方法转载
接口和抽象类
简要说明
当初在学习Java的时候,对于接口和抽象类的概念不是十分清晰,感觉二者几乎一样,没有什么本质的区别,在这个假期第二次读了《Android源码设计模式解析与实战》后,深刻认识到了抽象类和接口的重要性,在这里和大家一起梳理一下二者。参考资料
/article/4719052.html/article/1384930.html
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 SimpleInterface class 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 class DoSomeOtherWork 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方法中选择哪一个,因此产生了二义性。
相关文章推荐
- AIDL介绍和实例讲解
- 深入理解TAILQ队列(转自http://blog.csdn.net/hunanchenxingyu/article/details/8648794)
- (110) Connection timed out的错HttpClient 每次请求未close导致 Nginx connect failed (110- Connection timed out)
- 一个母婴电子商务网站的大数据平台及机器学习实践
- 大数据文件和小数据文件读取
- 在MainActivity的内部静态类PlaceholderFragment 类中的onCreateView中获取fragment_main.xml中控件
- 关于AI的目标导向型行动计划
- 游戏人工智能开发之6种决策方法
- 流式大数据处理的三种框架:Storm,Spark和Samza
- SQL 大数据查询如何进行优化?
- STL 之随机访问迭代器 http://blog.csdn.net/tangaowen/article/details/7515558
- 使用stl中的 advance和 distance 方法来进行iterator的加减 http://blog.csdn.net/tangaowen/article/details/7515558
- 置顶] 简单的程序诠释C++ STL算法系列之十三:copy http://blog.csdn.net/jerryjbiao/article/details/7376088
- Better Business Grammar Train Summary
- gitlab push时报错error:failed to push some refs to 'git@xxx.xx.xx.xxx:xxxx/xxx.git'
- 树莓派2安装win 10 IoT
- 【Lintcode】Restore IP Addresses, Number of Airplanes in the Sky
- 无法解决 equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_90_CI_AI" 之间的排序规则冲突。的解决方法
- LeetCode 217. Contains Duplicate
- Failed to locate or generate matchin signing assets