目录
1.Java接口可以定义常量么?接口可以定义变量么?
2.java接口中还可以在定义接口?
3.为什么要定义内部接口?
4.java接口的特点?
4.1 java8版本之前的特点
4.2 java8 版本之后的特点
5.项目中的常量是放在接口中,还是放在实现类中?
6.Java中的Nested Classes和Inner Classes
7.java8 default实体函数
8.java接口与抽象类的区别
8.1 不同点
8.2 相同点
8.3 抽象类
8.4 什么时候用接口,什么时候用抽象类?
1.Java接口可以定义常量么?接口可以定义变量么?
接口只可以定义常量,不能变量。可以定义String a = "aa";
2.java接口中还可以在定义接口?
接口必须是public修饰的?不是,可以有内部接口。
例如(Map接口的源码):
public interface Map
interface Entry{
K getKey();java接口
}
void clear();
}
内部接口又称为内嵌接口,意味着一个接口在另外的接口中申明。
3.为什么要定义内部接口?
- It is a way of logically grouping interfaces that are only used in one place.(这种接口值呢能被用于一个地方)
- It increases encapsulation.(封装)
- Nested(嵌套) interfaces can lead to more readable and maintainable code.
How Inner Interface Works?
To figure out how inner interface works, we can compare it with nested classes. Nested classes can be considered as a regular method declared in outer class. Since a method can be declared as static or non-static, similarly nested classes can be static and non-static. Static class is like a static method, it can only access outer class members through objects. Non-static class can access any member of the outer class.(可以与嵌套类比较)
MapImpl.java
|
当然,也是可以直接
public class ImplEntry implements Map.Entry{
public int getKey() {
return 0;
}
}
4.java接口的特点?
java接口:在java 8前后发生了变化
4.1 java8版本之前的特点
接口里只能有静态全局常量和public修饰的抽象方法。
为了代码简洁,在接口中方法可以不用public和abstract修饰,但是编译后的方法仍然是public abstract类型的方法。全局常量也可以不用public static fianl修饰,同样编译后仍然为public static final类型。
下面代码演示了一个如何定义一个1.8版本之前的接口:
public interface apple
{
String info = "静态常量";
void getPrice(); //其实平时我们没有定义 public abstract 但是其实编译的时候加上了,不过就算我们加上public,编译器其实会提醒我们并没啥卵用
}
4.2 java8 版本之后的特点
打破了1.8之前接口里只能有全局静态常量和public抽象方法的限制。允许接口中用default关键字修饰的实体方法出现(该方法在实现类中可以被覆写)
也允许在接口中定义public static 类型的实体函数,该静态由接口调用。
package a;
public interface Apple extends Fruit {
static void showSomething() {
System.out.println("这是Java1.8才支持的静态函数,该函数只能由接口调用");
}
public static final String info = "静态常量";
default void printSomething() {
System.out.println("这是Java1.8才支持的default实体函数.该方法可以在子类中被覆写。");
}
String MON = "Mon";
interface appleSweet {
int getPrice();
}
String test(String a);
}
package a;
public class AppleImpl implements Apple.appleSweet {
@Override
public int getPrice() {
Apple.showSomething();
return 1;
}
}
通过编译器证明,如果想要使用default修饰实体方法,必须显示的声明,否则会报错
调用这个函数,可以通过接口直接调用
这两个代码综合了上述的一些知识
目的是支持流(stream)
5.项目中的常量是放在接口中,还是放在实现类中?
有一种借口是常量接口,用于避免用类名来修饰常量名。常量接口模式是对接口的不良使用。
(不能用!!)
如果大量利用工具类导出的常量,可以通过利用静态导入(static import)机制,避免用类名来修饰常量名,不过静态导入机制是Java发行版本1.5中才引入的。
接口应该只被用来定义类型,他们不应该被用来导出常量。(接口中不建议定义常量)
接口是行为抽象,不是属性抽象!
6.Java中的Nested Classes和Inner Classes
嵌套类:嵌套类包括两种,static 和 non-static。
静态的嵌套类我们叫做静态嵌套类,而非静态的嵌套类我们成为内部类。
比如说我们创建一个静态嵌套类:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
关于静态嵌套类存在的意义是,它能直接获得其外部类的静态成员变量,使用嵌套静态类的意义实际上并不大。
内部类对象是依附于其外部类的对象存在而存在的,也就是说,如果我们要创建内部类的对象,首先我们必须要创建外部类的对象,然后才能创建内部类的对象,内部类可以直接获取外部类的字段(fields )和方法(methods )。创建内部类的方式如下:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
内部类由于依赖外部类的对象,因此其不能定义静态变量(static final除外)。
所以,关于静态嵌套类和内部类的区别是:
静态嵌套类不会持有外部类的应用,而内部类会持有外部类的引用。
静态嵌套类的实例化不需要先实例化外部类,而内部类的实例化需要先实例化外部类。
静态嵌套类并不能获取外部类的成员变量(只能获取其静态成员变量),而内部类即使其外部类的成员变量是私有的,仍然可以获取其变量(无论是否是静态的)。
原文:
7.java8 default实体函数
我们知道在java8之前 ,一个类实现一个接口需要实现接口所有的方法,
但是这样会导致一个问题,当一个接口有很多的实现类的时候,修改这个接口就变成了一个非常麻烦的事,需要修改这个接口的所有实现类
不过在java8中这个问题得到了解决,没错就是default函数;
interface DefaultInterface {
int operate(int a, int b);
default int addition(int a, int b) {
return a + b;
}
}
public class DefaultMethodTest implements DefaultInterface {
@Override
public int operate(int a, int b) {
return a - b;
}
public static void main(String[] args) {
DefaultMethodTest defaultMethodTest = new DefaultMethodTest();
System.out.println("5 + 3 = " + defaultMethodTest.addition(5, 3));
System.out.println("5 - 3 = " + defaultMethodTest.operate(5, 3));
}
}
java8很实用的方法,很多时候不想让所有实现类来实现的方法,就可以写成default
8.java接口与抽象类的区别
8.1 不同点
1 :接口里的成员属性全部是以 public(公开)、static(静态)、final(最终) 修饰符修饰
2 :接口里的成员方法全部是以 public(公开)、abstract(抽象) 修饰符修饰
3: 接口里不能包含普通方法,但是java8可以有静态方法,而且还有default修饰的default实体函数
4:子类继承接口必须实现接口里的所有成员方法,除非子类也是抽象类
5:一个类只能继承一个抽象类,而一个类却可以实现多个接口
6::接口强调特定功能的实现,而抽象类强调所属关系。
8.2 相同点
都不能被实例化,接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
现在网上的区别中,对于java8其实改动了很多,很多不适用了。
接口从设计角度来看,解决了java的单继承,来间接地实现多重继承。
8.3 抽象类
包含抽象方法的类称为抽象类,但并不意味着抽象类中只能有抽象方法,它和普通类一样,同样可以拥有成员变量和普通的成员方法。注意,抽象类和普通类的主要有三点区别:
1)抽象方法必须为public或者protected(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为public。
2)抽象类不能用来创建对象;
3)如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为为abstract类。
其他情况下,和普通类没有区别,那么也就是可以笼统来讲,含有抽象方法的类,是抽象类。
8.4 什么时候用接口,什么时候用抽象类?
1)抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。举个简单的例子,飞机和鸟是不同类的事物,但是它们都有一个共性,就是都会飞。那么在设计的时候,可以将飞机设计为一个类Airplane,将鸟设计为一个类Bird,但是不能将 飞行 这个特性也设计为类,因此它只是一个行为特性,并不是对一类事物的抽象描述。此时可以将 飞行 设计为一个接口Fly,包含方法fly( ),然后Airplane和Bird分别根据自己的需要实现Fly这个接口。然后至于有不同种类的飞机,比如战斗机、民用飞机等直接继承Airplane即可,对于鸟也是类似的,不同种类的鸟直接继承Bird类即可。从这里可以看出,继承是一个 "是不是"的关系,而 接口 实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系,比如鸟是否能飞(或者是否具备飞行这个特点),能飞行则可以实现这个接口,不能飞行就不实现这个接口。
2)设计层面不同,抽象类作为很多子类的父类,它是一种模板式设计。而接口是一种行为规范,它是一种辐射式设计。什么是模板式设计?最简单例子,大家都用过ppt里面的模板,如果用模板A设计了ppt B和ppt C,ppt B和ppt C公共的部分就是模板A了,如果它们的公共部分需要改动,则只需要改动模板A就可以了,不需要重新对ppt B和ppt C进行改动。而辐射式设计,比如某个电梯都装了某种报警器,一旦要更新报警器,就必须全部更新。也就是说对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
参考转载:
9. 静态导入机制好么?
从Java 5 开始引入了静态导入语法(import static),其目是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序
xx 类中的xx常量引入到本类中,这会使程序更简单,更容易阅读
目的是引入常量类,然后避免使用类名来修饰变量名。