Java基础——接口、lambda表达式与内部类

1、接口技术主要用来描述类具有什么功能,而并不给出每个功能的具体实现。
*接口中的成员和class定义不同之处:接口中常见的成员有两种:全局变量和抽象方法,而且都有固定的修饰符,都用public修饰的。
*接口特点
(1)接口不可以实例化
(2)覆盖接口中的所有抽象方法的子类才可以实例化,否则该子类还是一个抽象类;
(3)接口是用来实现的;
*类与接口的关系是实现(implement)关系
*继承是为了获取体系的基本关系,想要扩展功能可以通过接口实现(可以通过接口来解决多继承问题,转换为多实现),避免了单继承的局限性。

2、类实现接口的步骤:
(1)将类声明为实现给定的接口;
(2)对接口中的方法进行定义;
*类与类之间的关系是继承,类与接口之间的关系是实现,接口与接口之间的关系是继承,而且是多继承

3、Comparable接口中的compareTo方法将返回一个整数值,如果两个对象不相等,则返回一个正值或者一个负值。

4、接口的特性
(1)接口不是类,不能使用new运算符实例化一个接口
X = new Comparable(…);//error
尽管不能构造接口的对象,但能声明接口的变量
Comparable x;//ok
接口变量必须引用实现了接口的类对象
X = new Employee(…);//ok provided Employee implements Comparable
也可使用instance检查一个对象是否实现了某些特定的接口。
(2)接口中不能包含实例域或者静态方法,但可包含常量
(3)接口中的方法自动被设置为public,域被自动设为public static final
(4)每个类只能有一个超类,但可以实现多个接口;

5、接口与抽象类区别:
(1)类与类之间的关系是继承,类与接口之间的关系是实现;
(2)抽象类可以定义抽象和非抽象方法,子类可以使用或者覆盖使用;接口中定义的都是抽象方法,必须实现才能使用。

6、默认方法:可以为接口方法提供一个默认实现,必须用default修饰符标记这个方法。

7、解决默认方法冲突:情况:若现在一个接口中将一个方法定义为默认方法,然后又在超类或者另一个接口中定义了同样的方法,会如何?
解决:(1)超类优先。若超类提供一个具体方法,同名而且有相同参数类型的默认方法会被覆盖;
(2)接口冲突。若一个超接口提供一个默认方法,另一个接口提供了一个同名且参数类型(无论是否为默认参数)相同的方法,必须覆盖这个方法来解决冲突。

8、回调:一种常见的设计模式,可以指出某个特定时间发生时应该采取的动作。用到定时器,实现java.awt.event包的ActionListener接口。
Public interface ActionListener{
Void actionPerformed(ActionListener event)
}

9、Comparator接口
Comparator比较器能够按照长度递增对字符串进行排序,Comparable接口中的ComparaTor方法能够按照字典顺序比较字符串

10、Cloneable接口clone方法:复制(copy)一个新的对象,它的初始状态与原来的(original)相同,但之后它们各自会有不同的状态
Employee copy = original.clone();
Copy.raiseSalary(10);//OK—original unchanged
与此情况区分,原变量和副本都是同一个对象的引用(任何一个变量改变都会影响另一个变量)
Employee original = new Employee(“John”,5000);
Employee copy = original;
Copy.raiseSalary(10);//also changed original
*Object类中的clone方法声明为protected,子类只能调用受保护的clone方法来克隆自己,必须重新定义clone为public才能允许方法克隆对象,即实现Cloneable接口,将clone重新定义为public,再调用super.clone()。
*若在一个对象上调用clone方法,但没有实现Cloneable接口,Object类的clone方法会抛出CloneNotSupportException异常。

10、lambda表达式是一个可传递的代码块,可以在以后执行一次或者多次。带参数变量的表达式称为lambda表达式。
表达式形式:参数,箭头(->)以及一个表达式
*(1)若lambda表达式没有参数,仍要提供空括号,像无参数方法一样
(2)若方法只有一个参数,且这个参数类型可以推导得出,则可以省略小括号;
(3)无需指定lambda表达式的返回值;

11、函数式接口:对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式,这种接口就称为~。
*实际在java中,lambda表达式所能做的也只是能转换为函数式接口
*另一种表达式形式:用::操作符分隔方法名与对象或类名
Object::instanceMethod
Class::staticMethod
Class::instanceMethod
例:
System.out::println 等价于 x -> System.out.println(x)
Math::pow 等价于 (x,y) -> Math.pow(x,y)
String::compareToIgnoreCase 等价于 (x,y) -> x. compareToIgnoreCase (y)
this::equals 等价于 x -> this.equals(x) (也可使用super)
方法名也可为new,一位构造器引用
Person::new
Int[]::new 等价于 x -> new int[x]

12、lambda表达式的三个部分:
(1)一个代码块
(2)参数
(3)自由变量的值,是指非参数且不在代码中定义的变量(闭包)
*lambda表达式能够捕获外围作用域中的变量值,且必须为最终变量(变量初始化后就不会再给其赋新值)。

13、内部类:定义在另一个类中的类。
*使用内部类的原因:
(1)内部类可以访问该类定义所在的作用域中的数据,包括私有数据;
(2)内部类可以对同一个包中的其他类隐藏起来;
(3)想定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
*内部类与外部类区别:
(1)内部类可以直接访问外部类中的成员,外部类要想访问内部类,只能创建内部类的对象来访问;
(2)内部类相当于外部类的一个成员,可以被成员修饰符public、static、private修饰;
(3)内部类可以定义到局部位置上(注意:局部内部类只能访问被final修饰的局部变量);
*内部类的对象总有一个隐式引用(外部类对象的引用称为outer),它指向创建它的外部类对象。
*内部类中声明的所有静态域都必须是final。
*编译器把内部类翻译成用$分隔外部类名与内部类名的常规类文件。

14、内部类特殊语法规则:
*表达式OuterClass.this也可表示外部类引用;
*外部类引用内部类:OuterClass.innerClass

15、局部内部类:不能用public或private访问说明符进行声明,作用域被限定在声明这个局部类的块中。
*优势:对外部世界可以完全的隐藏起来。

16、匿名内部类:假如只创建这个类的一个对象,就不需要命名。这种类被称之为匿名内部类。例:
ActionListener listener = new ActionListener(){
………
};
*由于构造器的名字必须与类名相同,而匿名内部类没有类名,所以匿名内部类不能有构造器。
*匿名内部类的使用前提:内部类需要继承或者实现外部类的类或者接口。匿名内部类其实就是一个子类对象。

17、静态内部类:有时使用内部类只是为了把一个类隐藏到另一个类的内部,并不需要引用外部类对象,可将内部类声明为static,以便取消产生的引用。
*静态内部类除了没有对生成它的外部类对象的引用特权,与其它所有内部类完全一样。

18、代理:只有在编译时无法确定需要实现哪个接口时才有必要使用。
*使用代理的情况:若一个表示接口的Class对象在编译时无法确定其类型,代理类能够在运行时创建能够实现指定接口的类。代理类具有以下方法:
(1)指定接口所需要的全部方法;
(2)Object类中的全部方法,例如,toString、equals等
但不能再运行时定义这些方法的新代码,而是提供一个调用处理器(invocation handler),其实现了InvocationHandler接口的类对象,这个接口只有一个方法:
Object invoke(Object proxy, Method method, Object[] args);
无论何时调用代理对象的方法,调用处理器的invoke方法都会被调用,并向其传递Method对象和原始的调用参数。调用处理器必须给出处理调用的方法。

19、创建代理对象:使用Proxy类的newProxyInstance方法,方法有三个参数:
(1)类加载器(class loader),用null表示默认类加载器
(2)Class对象数组,每个元素都是要实现的接口
(3)调用处理器

20、代理类的特性:
(1)代理类在程序运行的过程中创建的
(2)所有的代理类都扩展于Proxy类。一个代理类只有一个实例域——调用处理器
(3)所有的代理类都覆盖了Object类中的方法toString、equals和hashCode
(4)没有定义代理类的名字,Sun虚拟机中的Proxy类将生成一个以字符串$proxy开头的类名
(5)对于特定的类加载器和预设的一组接口来说,只能有一个代理类
(6)代理类一定是public和final
(7)可以通过调用Proxy类中isProxyClass方法检测一个特定的Class对象是否代表一个代理类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值