接口
特殊的抽象类
- 所有的方法都是公开的抽象方法 (public abstract)
- 所有的属性都是公开静态常量 (public static final )
- 没有构造方法
- 可以定义静态方法 since JDK8
- 可以定义默认方法 since JDK8
interface IA{
int A = 10;
double B = 2.8;
void m1();
void m2();
static void print(){
System.out.println("hehe");
}
public default void m3(){
System.out.println("Xixi");
}
}
一个类实现接口 (implements 接口名) ,如果这个类不希望成为抽象类, 就必须实现接口中所有的抽象方法
接口的特性
- 接口之间可以继承, 而且可以定义多继承
interface ID extends IB , IC{
void m8();
}
- 一个类在继承另外一个类的同时, 还可以实现多个接口
class MyClass extends ClassE implements IA,ID{
public void m1(){}
public void m2(){}
public void m4(){}
public void m5(){}
public void m6(){}
public void m7(){}
public void m8(){}
public void m9(){}
}
接口的分类
-
常量接口 接口中没有方法, 只有常量定义
interface A{ int X = 10; double Y = 20; }
-
标记接口 接口中没有方法, 也没有常量
interface B{ }
-
普通接口 接口中定义多个抽象方法
interface C{ void m1(); void m2(); }
-
函数式接口 接口中只有一个抽象方法 since JDK8
interface D{ void m1(); } interface E{ void m1(); default void m2(){} }
接口的作用
-
多继承
一个类的多个父类, 只有一个居于主要地位(父类) , 剩余的都是附件功能 ( 接口 可XXXX的 )
-
把父类引用赋值给子类引用时, 需要强制类型转换,使得编译能够通过, 但运行时可能会有类型转换异常
-
子类引用赋值给父类引用, 可以直接赋值
-
没有继承关系的两个类的引用之间, 不能相互赋值
-
类的引用和接口的引用之间, 或两个接口的引用之间, 一定可以通过强制类型转换而赋值, 编译可以通过
-
-
多态 的 解耦合作用
接口: 标准
把标准的使用者 , 和标准的实现者分开, 达到 使用者和实现者的弱耦合
依赖倒转原则: 尽量和父类(接口)发生关系, 而拒绝与子类, 实现类发生关系
A —> B A–>I–B
- 接口回调
单一职能原则: 对象尽可能的简单 对象完成单一的功能 各司其职
开闭原则: 代码对修改关闭, 对扩展开放 方法: 将代码的不变性和代码的可变性分离
interface Predicate{
boolean test(Student s);
}
public static Student find5(Student[] ss , Predicate p){
for(int i = 0 ; i < ss.length ; i++){
if (p.test(ss[i])) return ss[i];
}
return null;
}
内部类
内部类: 定义在类之内的一个类 . 编译结束后, 内部类会被编译为一个独立的.class文件
局部内部类
作用范围: 定义开始, 到 所在的代码块结束
局部内部类不能定义静态成员
可以访问外部类的私有成员(包括静态的和非静态的), 还能访问外部类的局部变量 (加final) ( 局部变量不能被二次赋值 是常量)
class Outer{
private int a =10;
private static int b = 20;
public void method(){
int c = 30;
a++;
b++;
//c++; error!
class LocalInner{
public void print(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
LocalInner in = new LocalInner();
in.print();
}
}
匿名内部类
- 特殊的局部内部类 可以访问外部类的私有成员和局部常量
- 继承某个类, 或是实现某个接口
- 只会创建一个对象
class LocalInnerIAImplementationClass implements IA{
public void m1(){}
public void m2(){}
}
IA a1 = new LocalInnerIAImplementationClass();
IA a2 = new IA(){
public void m1(){}
public void m2(){}
};
匿名内部类无法定义构造方法 , 只有系统提供的默认构造方法
Lambda 表达式
匿名内部类的特殊写法 只能用于实现函数式接口
(形参列表) -> {方法实现} 形参类型可以省略
形参名 -> {方法实现} 如果形参表中只有一个参数, 可省略圆括号
(形参列表) -> 语句 如果方法实现只有一个语句, 可省略花括号
(形参列表) -> 返回值 如果方法实现只有一个返回语句 可省略return关键字, 和分号
成员内部类 可以访问外部类的私有成员(静态和非静态)
先创建外部类对象,再通过“外部内.new 内部类类名()”创建内部类对象
外部类类名.this 引用外部类的当前对象
public static void main(String[] args){
Outer o1 = new Outer(10);
Outer o2 = new Outer(20);
Outer.MemberInner in1 = o1.new MemberInner();
in1.print();//40 30 10 20
Outer.MemberInner in2 = o2.new MemberInner();
in2.print();//40 30 20 20
}
class Outer{
private int a = 10; //a1
private static int b = 20;
public Outer(int a){
this.a = a;
}
class MemberInner{
int a = 30; //a2
public void print(){
int a = 40; //a3
System.out.println(a); //40 //a3
System.out.println(this.a); //30 //a2
System.out.println(Outer.this.a); //10 //a1
System.out.println(b);//20
}
}
}
静态内部类 只能访问外部类的静态成员
class Outer{
private int a =10;
private static int b = 20;
static class StaticInner{
public void print(){
//System.out.println(a); error!
System.out.println(b);
}
}
}