接口
接口的实现
1.创建接口类
2.非抽象类实现接口需要对接口进行重写
public class Cat implements Jumping{
@Override
public void jump() {
System.out.println("猫可以跳高了");
}
}
public interface Jumping {
public abstract void jump();
}
抽象类实现接口也可以不对接口进行重写,但是将来他具体的子类要继承该父类还是需要重写接口的方法。
public abstract class Cat implements Jumping{
}
3.接口是抽象的,不可以实例化,比如如果Jumping是一个接口,那么就不能实现Jumping j=new Jumping();
接口是对行为进行抽象。但如果想实现实例化也不是不可以可以参考多态的方式进行实例化:(通过实现类对接口实例化这叫接口多态)Jumping j=new Cat();
j.jump();
4.接口用关键字interface修饰
5.类实现接口用implements表示------ public class 类名 implements 接口名{}
6.接口内部的方法必须为抽象方法,public abstract 类型 方法名( ){ },但因为是默认方法为抽象的,不写public abstract也行。
7.类与类之间是实现继承关系,接口与类是实现关系。
接口的成员特点
1.只有常量,还是静态的
接口内部默认只能是常量,即使你写public int num=2;
,也默认是个final,不能对num进行修改
接口内的常量是静态的,在测试类中可以通过接口名输出接口内部的常量。
public class Demo {
public static void main(String[] args) {
System.out.println(Jumping.num);//jumping是一个接口,num是它的静态常量
}
}
也就是说你写int num=10
和public static final int num=10
效果一样的。
2.接口没有构造方法,接口是对行为进行抽象,不需要具体存在
之前在学父类的时候,我们有说过子类的构造方法第一行默认出现一个super()—父类的无参构造,如果接口没有构造方法,那么类实现接口,在对类进行构造的时候这个super怎么办?
类Object是类层次结构的根,每个类都有Object作为父类,如果一个类没有父类就继承Object,如果有父类就间接继承Object。
Object只有一个无参构造Object();
这两个一样的:public class 子类名 implements 接口名{}
public class 子类名 extends Object implements 接口名{}
3.接口里面不能有非抽象方法,可以有抽象方法(抽象类方法不能有主体,也就是{ }),先让非抽象类实现接口,再在非抽象类内部进行接口方法的重写,就可以调用接口的方法了。
接口里的方法默认为抽象列,所有public abstract void method();
与void method
一样的。
总结:
类和接口的关系
类可以实现多个接口:public abstract class Cat implements Jumping,Run,Eat{ }
只能继承一个类:public abstract class Cat extends Animals{ }
可以同时继承和实现:public abstract class Cat extends Animals implements Jumping,Run,Eat{ }
接口和接口就是继承关系了,可以单继承可以多继承:public interface Jumping extends Inter1,Inter2{ }
类与类只能单继承
接口和抽象类的区别
重点在于设计层面的区别:举个例子,门和报警器,open,close这两个方法是属于门的,有报警器的门拥有报警功能,这个算是额外附加的,最好的处理方法就是将open和close两个方法放在门的抽象类,然后添加一个报警接口,接口有一个抽象方法报警,让拥有报警功能的报警门继承门并且实现报警接口
public class AlarmDoor extends Door implements Alarm{ }
AlarmDoor
是一个子类,Door
是一个父类,Alarm
是一个接口。对于这个例子我们可以可以这样理解,门是一个主体,报警器是一个配件,是附加物。接口内部的方法就相当于附加物拥有的功能,抽象类的方法是主体拥有的功能,我们如果在接口内部添加close和open的方法显然不合理,因为这两个功能是门的而不是报警器的。
报警门就是在原始门的基础上增加了一个报警器,所有子类继承门的父类,实现接口报警器。
(再次强调抽象类是对事物的抽象,而接口是对行为的抽象)
形参和返回值
类名作为形参和返回值
方法的形参是类名,其实需要的是该类的对象,方法的返回值是类名,其实返回的是该类的对象(不知道有啥用,先扔这,以后有需要再补充)
非抽象类直接通过类创建对象进行操作就行,如果是抽象类,因为不能实例化,所以要先创建一个子类继承这个抽象类,通过多态的方式进行实例化抽象类 对象名=new 子类
;产生了我们需要类的对象就可以开始调用了,可以作为形参也可以作为返回值。
多态编译看左边,执行看右边。(执行的方法是右边的方法,对象的类型是左边的类型)
方法的形参是抽象类名,其实需要的是该抽象类的子类对象
方法的返回值是抽象类名,其实返回的是该抽象类的子类对象
接口名作为形参和返回值
形参和返回值都需要一个对象,众所周知接口不能实例化,所以同上,通过多态的方法实现接口的实例化:
定义一个类实现接口,然后在类内部重写接口的抽象方法,通过多态类名 对象名=new 接口名
创建了一个对象,就可以进行操作了。
编译看左边,执行看右边。
方法的形参是接口名,其实需要的是该接口的实现类对象
方法的返回值是接口名,其实返回的是该接口的实现类对象
比较器总结
1.内部比较器
public class ClassName implements Comparable<Object>{
public ClassName{
}
public int compareTo(Object o){
return this.-o.;//升序
}
}
Collections.sort(array);
2.外部比较器
public class MyComparator implements Comparator<Object>{
public int compare(Object first,Object second){
return first.-second.;//升序
//String类型就用(first.).compareTo(second.)
}
}
Collections.sort(array,new MyComparator());
3.匿名内部类
Collections.sort(array,new Comparator<Object>{
public int compare(Object first,Object second){
return first.-second.;
}
});
4.Lambda
Collections.sort(array,(first,second)->{
return frist.-second.
});