接口,Comparable和Comparator
1.抽象类和接口的区别
抽象类
含有abstract修饰符的class 即为抽象类,abstract类不能创建实例对象,含有abstract的方法的类必须定义为abstract class ,abstract class 里的方法不必是抽象的,抽
象类定义抽象方法必须放在具体子类中实现,所以,不能有抽象的构造方法或抽象的静态方法,如果子类没有实现抽象父类中的所有方法,那么,子类也必须定义为抽象类。
接口(interface):
可以说成是抽象类的特例。接口中的所有方法都必须是抽象的,接口中的方法定义默认为public abstract 。接口中的变量是全局常量,即public static final修饰的。
在语法上的区别:
a. 抽象类里可以有构造方法,而接口内不能有构造方法。
b. 抽象类中可以有普通成员变量,而接口中不能有普通成员变量。
c. 抽象类中可以包含非抽象的普通方法,而接口中所有的方法必须是抽象的,不能有非抽象的普通方法。
d. 抽象类中的抽象方法的访问类型可以是public ,protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认即为public abstract类型。
e. 抽象类中可以包含静态方法,接口内不能包含静态方法。
f. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static类型,并且默认为public static类型。
g. 一个类可以实现多个接口,但只能继承一个抽象类。
设计思想上的区别:
抽象类:找到类和类之间的共性,慢慢向上提取,一种自底而上抽象出来的
对象-->类-->父类-->抽象类
接口:考虑不同类之间的通用功能的扩展,一种自顶向下的设计思想
创建一个飞的接口,超人飞,小鸟飞,飞机飞,都要实现这个接口
再补充点两者在应用上的区别:
a. 接口更多的是在系统框架设计方法发挥作用,主要定义模块之间的通信,而抽象类在代码实现方面发挥作用,可以实现代码的重用。
b. 在JDK1.8之后可以添加有实现的方法。
2.什么是接口
Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。
接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。一旦类实现了接口,类就可以支持接口所指定的所有属性和成员。
3.使用接口的好处
a.弥补了java不能多继承的缺点
b.
4.接口的使用步骤:
1.实现接口 implements
2.重写方法
3.传递接口实现类 使用instantsOf
5.理解(转)
这个问题这困扰了我很久,后来我才想明白,大家都说接口就是实现扩展功能用的,这句话其实是最误导人的,因为接口本身并没有实现方法,它只是一条路,是一个工具,千万别想复杂,真正实现功能扩展的是实现方法的对象和调用接口的方法。下面举个栗子。
狗这个类继承了走兽类,它有跑,跳,啃,等方法。但是它不会飞,它的父类也没有这个方法。但是你想让狗有飞这个功能,怎么办呢?当然你可以直接在狗的类中给它添加一个飞的方法就行了。有可能你并不会写这个方法,或者是这个方法需要几千几万行代码,硬写吗?那以后你还想要猪,牛,羊等等都可以飞呢?那又怎么办呢?这时候你发现你有一个类,这个类就叫飞行兽吧。它有一个方法就是飞行,这下好了,你决定让狗继承它,结果发现不能多继承,你又想让狗的父类继承它,结果发现还有其他的走兽不能让他们飞。这时候就需要接口出来了,这个接口我们叫它插翅膀吧,这个接口有一个方法就是插翅膀,但没有实现,因为接口不管你怎么给狗插翅膀。同时你还发现在飞行兽里有一个带参数的构造方法,而参数类型就是这个接口类型。但是狗的类型是狗而不是接口类型,没法作为参数传进去,这时你就可以让狗实现这个接口,这个狗对象就成了插了翅膀的狗,接着通过多态的原理把插了翅膀的狗这个对象传给飞行兽,这狗这就成了飞行兽,可以飞了。
ChiBang chibangdog=new Dog()
FlyShou flydog =new FlyShou(chibangdog)
可以飞的狗就出来了,以后要猪飞就让猪实现插翅膀,要羊飞就让羊实现插翅膀,要牛飞就......直接吹吧。不知道这样说明白没有。
1 //实现Comparable类 2 public class Student implements Comparable<Student> { 3 private String name; 4 private int age; 5 private int iD; 6 7 public Student(String name, int age, int iD) { 8 super(); 9 this.name = name; 10 this.age = age; 11 this.iD = iD; 12 } 13 14 @Override 15 public String toString() { 16 return "Student [name=" + name + ", age=" + age + ", iD=" + iD + "]"; 17 } 18 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public int getAge() { 28 return age; 29 } 30 31 public void setAge(int age) { 32 this.age = age; 33 } 34 35 public int getiD() { 36 return iD; 37 } 38 39 public void setiD(int iD) { 40 this.iD = iD; 41 } 42 43 @Override 44 public int compareTo(Student o) { 45 46 return this.age - o.age; 47 } 48 49 } 50 51 public class School { 52 private Student[] students; 53 54 public Student[] getStudents() { 55 return students; 56 } 57 58 public void setStudents(Student[] students) { 59 this.students = students; 60 } 61 62 @Override 63 public String toString() { 64 return "School [students=" + Arrays.toString(students) + "]"; 65 } 66 67 } 68 69 public class SchoolTest { 70 public static void main(String[] args) { 71 School sc = new School(); 72 Student[] students = new Student[3]; 73 // Student stu = null; 74 75 students[0] = new Student("林青霞", 18, 1); 76 students[1] = new Student("杨坤", 12, 2); 77 students[2] = new Student("周杰伦", 20, 3); 78 sc.setStudents(students); 79 // 我们调用数组排序的方法,但是数组sort排序又调用了我们的comparable的compareTo方法,我们没有实现这个接口,所以castClassException,
//所以我们要实现这个接口,重写方法,这样sort就不会报警了,但是他需要接受一个比较值,正数负数或者0,所以我们就要重写这个比较方法。 80 81 Arrays.sort(students); 82 System.out.println(sc.toString()); 83 84 } 85 86 } 87 88 //sort内部使用学生类调用了compareTo 89 // Find end of run, and reverse range if descending 90 if (((Comparable) a[runHi++]).compareTo(a[lo]) < 0) { // Descending 91 while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) < 0) 92 runHi++; 93 reverseRange(a, lo, runHi); 94 } else { // Ascending 95 while (runHi < hi && ((Comparable) a[runHi]).compareTo(a[runHi - 1]) >= 0) 96 runHi++; 97 } 98 99 return runHi - lo; 100 } 101 School [students=[Student [name=杨坤, age=12, iD=2], Student [name=林青霞, age=18, iD=1], Student [name=周杰伦, age=20, iD=3]]]
//自定义比较器,调用的是sort(T[] a, Comparator<? super T> c) // 根据指定比较器产生的顺序对指定对象数组进行排序。 public class Student { private String name; private int age; private int iD; public Student(String name, int age, int iD) { super(); this.name = name; this.age = age; this.iD = iD; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", iD=" + iD + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getiD() { return iD; } public void setiD(int iD) { this.iD = iD; } } //比较器 public class StudentTest { public static void main(String[] args) { Student st1 = new Student("zs", 12, 1); Student st2 = new Student("ls", 10, 2); Student st3 = new Student("ww", 19, 3); Student[] students = { st1, st2, st3 }; Arrays.sort(students, new MynameascComparator()); System.out.println(Arrays.toString(students)); } } //测试类 public class MynameascComparator implements Comparator { @Override public int compare(Object o1, Object o2) { if (o1 instanceof Student && o2 instanceof Student) { Student one = (Student) o1; Student another = (Student) o2; return one.getName().compareTo(another.getName()); } return 0; } } 执行结果: [Student [name=ls, age=10, iD=2], Student [name=ww, age=19, iD=3], Student [name=zs, age=12, iD=1]]
//使用匿名内部类改写Comparator public class Student { private String name; private int age; private int iD; public Student(String name, int age, int iD) { super(); this.name = name; this.age = age; this.iD = iD; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", iD=" + iD + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getiD() { return iD; } public void setiD(int iD) { this.iD = iD; } } import java.util.Arrays; import java.util.Comparator; public class StudentTest { public static void main(String[] args) { Student st1 = new Student("zs", 12, 1); Student st2 = new Student("ls", 10, 2); Student st3 = new Student("ww", 19, 3); Student[] students = { st1, st2, st3 }; Arrays.sort(students, new Comparator() { @Override public int compare(Object o1, Object o2) { if (o1 instanceof Student && o2 instanceof Student) { Student one = (Student) o1; Student another = (Student) o2; return one.getName().compareTo(another.getName()); } return 0; } }); System.out.println(Arrays.toString(students)); } } 执行结果 [Student [name=ls, age=10, iD=2], Student [name=ww, age=19, iD=3], Student [name=zs, age=12, iD=1]]
6.匿名内部类
本质:匿名内部类会隐式的继承一个类或者实现一个接口,或者说,匿名内部类是一个继承了该类或者实现了该接口的子类匿名对象。
格式:
new 类名/接口/抽象类(){
//要重写的方法
}