作者:~小明学编程
文章专栏:JavaSE基础
格言:目之所及皆为回忆,心之所想皆为过往
目录
_____________________________________________________________________________
什么是接口
接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量。
语法规则
1.使用 interface 来修饰定义一个接口。
2.接口中的方法一定是抽象方法, 因此可以省略 abstract。
3.接口中的方法一定是 public, 因此可以省略 public。
4.接口当中的普通方法不能有具体的实现,如果非要实现的话只能通过default来实现。
5.接口当中可以有static的方法。
6.接口是不能通过new()来实例化的。
7.类和接口的关系是通过implements来实现的。
8.当一个类实现了一个接口就必须重写接口当中的抽象方法。
9.接口当中的成员变量默认是public static final修饰的。
10.当一个类实现这个接口之后,当我们重写这个方法的时候,必须在方法前面家伙是那个public。
11.一个类可以通过extends继承一个抽象类或者普通类,但是可以通过implements实现多个接口。
12.接口前如interface IShape也可以写成 abstract nterface IShape。
interface IShape {
public int a = 10;
void draw();
default void fun()
{
System.out.println("hello");
}
static void fun1()
{
System.out.println("Hi");
}
}
class Rect implements IShape{
@Override
public void draw() {
System.out.println("□");
}
@Override
public void fun() {
System.out.println("Hello");
}
}
class Flower implements IShape {
@Override
public void draw() {
System.out.println("♣");
}
}
class Cycle implements IShape {
@Override
public void draw() {
System.out.println("○");
}
}
接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static).
interface IA{
void draw();
public static final int num = 10;
}
并且我们要注意的是接口中我们定义的是静态常量,所以必须得给他赋一个初值否则就会报错。
还有就是我们的public static final都可以省略,会默认这个num就是public static final类型的,所以为了代码的简洁我们可以写成
interface IA{
void draw();
int num = 10;
}
其中的 public, static, final 的关键字都可以省略. 省略后的 num 仍然表示 public 的静态常量。
1. 我们创建接口的时候, 接口的命名一般以大写字母 I 开头.
2. 接口的命名一般使用 "形容词" 词性的单词.
3. 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性
注意在我们重写接口方法的时候一定要注意权限
interface IA{
void draw();
int num = 10;
}
class B implements IA {
void draw() {
System.out.println("hello_world");
}
}
这里我们的代码将会报错,因为我们想要实现IA然后重写IA里面的draw方法但是我们接口里面的方法默认是public的,而我们类B中默认的却是default所以重写不成功将会报错。
实现多个接口
有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的。然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果。
interface IA{
void draw();
int num = 10;
}
interface IB{
void draw2();
}
class ClassC{
public void draw3(){
System.out.println("hello");
}
}
class B extends ClassC implements IA,IB {
public void draw() {
System.out.println("hello_world");
}
@Override
public void draw2() {
System.out.println("hello_hi");
}
}
public class Test2 {
public static void main(String[] args) {
B b = new B();
b.draw();
b.draw2();
b.draw3();
}
}
这里我们的类B不仅继承了ClassC这个类同时通过接口实现了IA和IB,这就是我们的实现多个接口的方法。
接口间的继承
接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字。
interface IA{
void draw();
int num = 10;
}
interface IB extends IA{
void draw2();
}
class ClassC implements IB {
@Override
public void draw() {
System.out.println("hello");
}
@Override
public void draw2() {
System.out.println("hi");
}
}
public class Test {
public static void main(String[] args) {
ClassC classC = new ClassC();
classC.draw();
classC.draw2();
}
}
我们的接口也可以继承接口(可以继承多个接口)但是当我们要实现这个接口的时候必须重写当前接口和接口所继承的接口里面的所有抽象方法。
接口的实际应用
class Student implements Comparable<Student>{
public int age;
public String name;
public double score;
public Student(int age, String name, int score) {
this.age = age;
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score=" + score +
'}';
}
@Override
public int compareTo(Student o) {
if(this.age>o.age){
return 1;
} else if (this.age<o.age) {
return -1;
}else {
return 0;
}
}
}
public class Test {
public static void main(String[] args) {
Student[] student = new Student[3];
student[0] = new Student(18,"xiaobai",99);
student[1] = new Student(17,"bai",83);
student[2] = new Student(19,"xi",89);
Arrays.sort(student);
System.out.println(Arrays.toString(student));
}
}
这里我们重写了compareTo这个接口然后我们可以对student进行排序最后打印。
这里有一个明显的缺点就是这种排序的方式对类的侵入性太大了,我们这种写法很再对分数和姓名再次进行一个排序了。
下面我们再介绍一种写法:
class Student {
public int age;
public String name;
public double score;
public Student(int age, String name, int score) {
this.age = age;
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", score=" + score +
'}';
}
}
class AgeCompare implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.age- o2.age;
}
}
class ScoreCompare implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return (int)(o1.score- o2.score);
}
}
class NameCompare implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.name.compareTo(o2.name);
}
}
public class Test {
public static void main(String[] args) {
Student[] student = new Student[3];
student[0] = new Student(18,"xiaobai",99);
student[1] = new Student(17,"bai",83);
student[2] = new Student(19,"xi",89);
AgeCompare ageCompare = new AgeCompare();
ScoreCompare scoreCompare = new ScoreCompare();
NameCompare nameCompare = new NameCompare();
Arrays.sort(student,ageCompare);
System.out.println(Arrays.toString(student));
Arrays.sort(student,scoreCompare);
System.out.println(Arrays.toString(student));
Arrays.sort(student,nameCompare);
System.out.println(Arrays.toString(student));
}
}
这种写法可以根据我们想要的排序方式进行排序,这种写法侵入性比较小。