Java中:接口,抽象类,内部类
2018-01-15 11:04
239 查看
Java8中的接口
public interface Output { //接口里定义的成员变量只能是常量 //默认使用public static final修饰 int MAX_CACHE_LINE = 50; //接口里定义的普通方法只能是public的抽象方法 void out(); void getData(String msg); //接口中定义的默认方法,需要使用default修饰 default void print(String... msgs) { for (String msg : msgs) { System.out.println(msg); } } //接口中定义类方法,需要使用static修饰 static String staticTest(){ return "接口里的类方法"; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Java8中允许在接口中定义默认方法,默认方法必须使用default修饰,该方法不能使用static修饰,无论程序是否指定,默认方法总是使用public修饰。由于默认方法并没有static修饰,因此不能直接使用接口来调用默认方法,需要使用接口的实现类的实例来调用这些默认方法。
Java8中允许在接口中定义类方法,类方法必须使用static修饰,该方法不能使用default修饰,无论程序是否指定,类方法总是使用public修饰。类方法可以直接使用接口来调用。
接口和抽象类
相同点 接口和抽象类都不能被实例化,他们都位于继承树的顶端,用于被其他类实现和继承。
接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
区别:
接口里只能包含抽象方法和默认方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法。
接口里不能定义静态方法;抽象类里可以定义静态方法。
接口里只能定义静态常量,不能定义普通成员变量;抽象类里则既可以定义普通成员变量,也可以定义静态常量。
接口里不包含构造器;抽象类里可以包含构造器,抽象类里的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
接口里不能包含初始化块;但抽象类则完全可以包含初始化块。
一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足。
内部类
把一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类(也叫嵌套类),包含内部类的类也被称为外部类(也叫宿主类)内部类比外部类可以多用三个修饰符:private、protected、static
非静态内部类不能拥有静态成员
在一个类的方法中定义的内部类叫做局部内部类;其他的叫做成员内部类。
非静态内部类
成员内部类中没有使用static修饰的内部类是非静态内部类
非静态内部类对象和外部类对象的关系是?
非静态内部类对象必须寄生在外部类对象里,而外部类对象则不必一定有费静态内部类对象寄生其中。如果存在一个非静态内部类对象,则一定存在一个被他寄生的外部类对象。
但外部类对象存在时,外部类对象里不一定寄生了非静态内部类对象。
因此外部类对象访问非静态内部类成员时,可能非静态普通内部类根本不存在。
而非静态内部类对象访问外部类成员时,外部类对象一定存在。
静态内部类
使用static修饰的内部类被称为静态内部类(也叫类内部类)。这个内部类属于外部类本身,而不属于外部类的某个对象。静态内部类可以包含静态成员,也可以包含非静态成员。
为什么静态内部类的实例方法不能访问外部类的实例属性?
静态内部类是外部类的类相关的,而不是外部类的对象相关的。静态内部类对象不是寄生在外部类的实例中,而是寄生在外部类的类本身中。
当静态内部类对象存在时,并不存在一个被他寄生的外部类对象,静态内部类对象只持有外部类的类引用,没有持有外部类对象的引用。
如果允许静态内部类的实例方法访问外部类的实例成员,但找不到被寄生的外部类对象,这将引起错误。
局部内部类
如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。实际开发很少使用
匿名内部类
匿名内部类适合创建那种只需要一次使用的类。创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。
匿名内部类格式:
new 实现接口() | 父类构造器(实参列表) { //匿名内部类的类体部分 }1
2
3
4
5
最常用的创建匿名内部类的方式是需要创建某个接口类型的对象
interface Product { public double getPrice(); public String getName(); } public class AnonymousTest { public void test(Product p) { System.out.println("买了一个" + p.getName() + ",花了" + p.getPrice()); } public static void main(String args[]) { AnonymousTest ta = new AnonymousTest(); //调用test方法时,需要传入一个Product参数 //此处传入其匿名实现类的实例 ta.test(new Product() { @Override public double getPrice() { return 12.3; } @Override public String getName() { return "U盘"; } }); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Lambda表达式
Lambda表达式支持代码块作为方法参数,允许使用更简洁的代码来创建只有一个抽象方法的接口(这种接口被称为函数式接口)的实例。比如,有匿名内部类程序:
public class CommandTest { public static void main(String args[]) { ProcessArray pa = new ProcessArray(); int[] target = {2, 1, -5, 3}; pa.process(target, new Command() { @Override public void process(int[] target) { int sum = 0; for (int tmp : target) { sum += tmp; } System.out.println("数组元素的总和是:" + sum); } }); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
改为Lambda表达式代替匿名内部类:
public class CommandTest { public static void main(String args[]) { ProcessArray pa = new ProcessArray(); int[] target = {2, 1, -5, 3}; pa.process(target, (int[] array) -> { int sum = 0; for (int tmp : array) { sum += tmp; } System.out.println("数组元素的总和是" + sum); }); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
版权声明:本文为博主原创文章,转载请注明来源,感谢!
相关文章推荐
- Java中的抽象类,接口,内部类
- java基础知识---多态、抽象类、接口、内部类
- Java基础之面向对象(抽象类、接口、内部类)
- Java学习系列(五)Java面向对象之抽象类、接口、内部类、枚举类详解
- java基础---接口、抽象类、内部类
- Java之接口与内部类6.2.1--抽象类
- 3.java面向对象语法学习(部分2-抽象类,接口,内部类)
- 黑马程序员-----java 抽象类、接口、内部类
- Java 抽象类、接口、内部类
- Java基础笔记-继承、抽象类、接口、多态、内部类、异常
- Java学习_0712接口、抽象类内部类,继承
- java(单例模式、抽象类、接口、内部类)
- java/final变量,final函数,抽象类,接口,内部类,object类
- Java之接口,抽象类,内部类
- 黑马程序员_Java基础_抽象类,模板设计模式,接口,内部类,多态
- Java学习总结(四)——面向对象(下)(接口,抽象类,内部类,String类等)
- java基础学习——内部类、抽象类、接口
- 黑马程序员——Java基础---面向对象(封装、继承、单例、抽象类、接口、内部类)
- Java基础——关于抽象类,接口和内部类(inner class)的相关知识
- Java基础07:重写;重载;内部类;抽象类;接口