13 接口、匿名内部类

lix_uan
• 阅读 1228

接口

定义格式

  • JDK7:包含抽象方法
  • JDK8:增加了默认方法和静态方法
  • JDK9:增加了私有方法

示例

interface Flyable{
    //静态常量
	long MAX_SPEED = 7900000;//这里单位是毫米/秒,7.9千米/秒,超过这个速度,就变成卫星
    
    //抽象方法
	void fly();
    
    //默认方法
    public default void start(){
        System.out.println("开始");
    }
    public default void stop(){
        System.out.println("结束");
    }
    
    //静态方法
    public static void broken(){
        System.out.println("飞行中遇到物体就坏了");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

接口的实现

  • 接口不能创建对象,但是可以被实现(implements)

    class Bird implements Flyable{
    
    	//重写/实现接口的抽象方法,【必选】
    	public void fly() {
    		System.out.println("展翅高飞");
    	}
    	
    	//重写接口的默认方法,【可选】
    	//重写默认方法时,default单词去掉
    	public void start(){
            System.out.println("先扇两下翅膀,一蹬腿,开始飞");
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public class TestInteface {
    	public static void main(String[] args) {
    		//创建实现类对象
    		Bird b = new Bird();
    		
    		//通过实现类对象调用重写的抽象方法,以及接口的默认方法,如果实现类重写了就执行重写的默认方法,如果没有重写,就执行接口中的默认方法
    		b.start();
    		b.fly();
    		b.stop();
    		
    		//通过接口名调用接口的静态方法
    		Flyable.broken();
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

接口的多实现

  • 接口中有多个抽象方法时,实现类必须重写所有抽象方法

  • 如果抽象方法有重名的,只需要重写一次

    【修饰符】 class 实现类  implements 接口1,接口2,接口3。。。{
    	// 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
      	// 重写接口中默认方法【可选】
    }
    
    【修饰符】 class 实现类 extends 父类 implements 接口1,接口2,接口3。。。{
        // 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写
      	// 重写接口中默认方法【可选】
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

冲突问题

亲爹优先原则

  • 当一个类,既继承一个父类,又实现若干个接口时,父类的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法

必须做出选择

  • 一个类同时实现了多个接口,而多个接口中包含方法签名相同的默认方法时,必须保留一个,或者选择自己完全重写

    interface A{
    	public default void d(){
    		System.out.println("今晚7点-8点陪我吃饭看电影");
    	}
    }
    interface B{
    	public default void d(){
    		System.out.println("今晚7点-8点陪我逛街吃饭");
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class C implements A,B{
    	@Override
    	public void d() {
    		A.super.d();
    	}
    }
    
    1
    2
    3
    4
    5
    6
    class D implements A,B{
    	@Override
    	public void d() {
    		System.out.println("自己待着");
    	}
    }
    
    1
    2
    3
    4
    5
    6

接口的多继承

  • 一个接口能继承另一个或者多个接口,接口的继承也使用extends关键字
  • 子接口重写默认方法时,default关键字可以保留
  • 子类重写默认方法时,default关键字不可以保留

其他特点

  • 接口中无法定义成员变量,但是可以定义常量,其值不可以改变2,默认使用public static final修饰
  • 接口中没有构造方法,不能创建对象
  • 接口中没有静态代码块

接口与实现类对象的多态引用

public class TestInterface {
	public static void main(String[] args) {
		Flyable b = new Bird();
		b.fly();
		
		Flyable k = new Kite();
		k.fly();
	}
}
interface Flyable{
    //抽象方法
	void fly();
}
class Bird implements Flyable{

	@Override
	public void fly() {
		System.out.println("展翅高飞");
	}
	
}
class Kite implements Flyable{

	@Override
	public void fly() {
		System.out.println("别拽我,我要飞");
	}	
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

经典接口介绍

java.lang.Comparable

public class TestComparable {
	public static void main(String[] args) {
		Student s1 = new Student(1,"张三",89);
		Student s2 = new Student(2,"李四",89);
		if(s1.compareTo(s2)>0){
			System.out.println("s1>s2");
		}else if(s1.compareTo(s2)<0){
			System.out.println("s1<s2");
		}else{
			System.out.println("s1 = s2");
		}
	}
}
class Student implements Comparable{
	private int id;
	private String name;
	private int score;
	
	//省略了构造器、get/set、toString等方法

	@Override
	public int compareTo(Object o) {
		//这些需要强制,将o对象向下转型为Student类型的变量,才能调用Student类中的属性
		Student stu = (Student) o;
		if(this.score != stu.score){
			return this.score - stu.score;
		}else{//成绩相同,按照学号比较大小
			return this.id - stu.id;
		}
	}	
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

java.util.Comparator

class StudentScoreCompare implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		Student s1 = (Student) o1;
		Student s2 = (Student) o2;
		return s1.getScore() - s2.getScore();
	}	
}
1
2
3
4
5
6
7
8
9
import java.util.Comparator;

public class TestComparator {
	public static void main(String[] args) {
		Student stu1 = new Student("张三",89);
		Student stu2 = new Student("李四",78);
		
		StudentScoreCompare ssc = new StudentScoreCompare();
		if(ssc.compare(stu1, stu2)>0){
			System.out.println(stu1 + ">" + stu2);
		}else if(ssc.compare(stu1, stu2)<0){
			System.out.println(stu1 + "<" + stu2);
		}else{
			System.out.println(stu1 + "=" + stu2);
		}
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

匿名内部类的使用

方式一:匿名内部类的对象直接调用方法

interface A{
	void a();
}
public class Test{
    public static void main(String[] args){
    	new A(){
			@Override
			public void a() {
				System.out.println("aaaa");
			}
    	}.a();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

方式二:通过父类或父接口的变量多态引用匿名内部类的对象

class B{
	public void b(){
		System.out.println("bbbb");
	}
}
public class Test{
    public static void main(String[] args){
    	B obj = new B(){
    		public void b(){
    			System.out.println("ccccc");
    		}
    	};
    	obj.b();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

方式三:匿名内部类的对象作为实参

interface A{
	void method();
}
public class Test{
    public static void test(A a){
    	a.method();
    }
    
    public static void main(String[] args){
    	test(new A(){

			@Override
			public void method() {
				System.out.println("aaaa");
			}    		
    	});
    }   
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
点赞
收藏
评论区
推荐文章

暂无数据

lix_uan
lix_uan
Lv1
学无止境,即刻前行
文章
7
粉丝
7
获赞
0