一、认识接口
1、生活中的接口-USB接口
解析:USB接口提供了尺寸、接电源、传输数据等一系列标准,各个厂家根据USB接口提供的一系列标准生产出了各种具有一定功能的USB产品,比如:USB风扇用于接电源后吹风,U盘用于接入USB接口后传输数据
2、编程界的接口(如Java接口)
(1)USB接口本身没有实现任何功能,但是规定了USB所具有的各种功能,并通过设计并制造出各种对应的USB设备来具体实现USB接口所具备的这些功能
(2)使用Java接口来实现USB接口
编写USB接口——————>根据需求设计方法
实现USB接口——————>实现所有方法
使用USB接口——————>通过多态的方式使用USB接口
二、认识Java接口以及Java接口的基本语法
1、面向接口编程
(1)在程序设计时关心实现类有什么能力,而不关心实现的细节
(2)面向接口的约定而不考虑接口的具体实现
2、从本质上讲,从抽象方法的角度来看,接口是一种更彻底的功能定义,是一种特殊的抽象类
3、接口的定义
(1)interface关键字
作用:用来声明接口
(2)定义接口的基本语法
【访问权限修饰符】 interface 接口名 【extends 其他的接口名1,......其他的接口名n】{
// 定义静态常量、抽象方法、静态方法(jdk8及以后)、默认方法(jdk8及以后)
}
(3)举例:在接口中只能定义静态常量、抽象方法、静态方法(jdk8及以后)、默认方法(jdk8及以后)
package com.ffyc.bcms.demo2;
public interface MyInterface {
int num=4;// 1、在接口定义中所有的属性默认被public static final修饰,不能省略或改变任何关键字之后进行显式修饰
void test();// 2、在接口中定义的抽象方法默认被public abstract修饰,不能省略或改变任何关键字之后进行显示修饰
// 3、在接口中定义静态方法,可通过接口名直接访问。默认被public修饰,不能省略或改变任何关键字之后进行显示修饰
public static void staticMethod(){
System.out.println("MytetInterface中的静态方法");
}
// 4、在接口中定义默认方法,需要使用类来继承,然后通过子类对其进行调用。默认被public修饰,不能省略或改变任何关键字之后进行显示修饰
default void defaultMethod(){
System.out.println("MytetInterface中的默认方法");
}
}
4、接口的主要作用-定义功能
5、接口的使用-创建实现类
(1)类通过使用implements关键字来实现接口(那么实现这个接口的类就是这个接口的实现类)。在类声明中,implements关键字必须放在class声明后面
(2)定义接口的实现类的基本语法
【访问权限修饰】 class 类名 implements 接口名1,接口名2......{}
(3)举例:
package com.ffyc.bcms.demo2;
import java.io.Serializable;
/*
* 类实现接口,实现接口的类就是实现类。
* 一个类可以实现多个接口。
* 类实现一个接口,就必须实现这个接口中的所有抽象方法
* */
public class MyInterfaceImpl implements MyInterface, Serializable {
@Override
public void test() {
System.out.println("MyInterfaceImpl实现了MyInterface中的test()");
}
public static void main(String[] args) {
/*通过子类对象调用接口中的默认方法*/
MyInterfaceImpl m=new MyInterfaceImpl();
m.defaultMethod();
/*通过接口名调用接口中的静态方法*/
MyInterface.staticMethod();
/*调用实现类重写后的test()方法*/
m.test();
/*通过接口名调用接口中的静态常量*/
System.out.println(MyInterface.num);
}
}
(4)注意
- 接口的默认方法也可以被重写,且被重写之后的方法会变为没有default修饰但被public修饰的普通非静态成员方法,在使用子类对象是先调用的是子类中被重写后的方法,如果子类中没有被重写后的方法才会调用接口中的默认方法
package com.ffyc.bcms.demo2;
import java.io.Serializable;
/*
* 类实现接口,实现接口的类就是实现类。
* 一个类可以实现多个接口。
* 类实现一个接口,就必须实现这个接口中的所有抽象方法
* */
public class MyInterfaceImpl implements MyInterface, Serializable {
@Override
public void test() {
System.out.println("MyInterfaceImpl实现了MyInterface中的test()");
}
@Override
public void defaultMethod() {
System.out.println("MyInterfaceImpl实现了MyInterface中的默认方法");
}
public static void main(String[] args) {
/*通过子类对象调用接口中的默认方法*/
MyInterfaceImpl m=new MyInterfaceImpl();
m.defaultMethod();
/*通过接口名调用接口中的静态方法*/
MyInterface.staticMethod();
/*调用实现类重写后的test()方法*/
m.test();
/*通过接口名调用接口中的静态常量*/
System.out.println(MyInterface.num);
}
}
三、接口的特点
package com.ffyc.bcms.demo3;
public abstract class Animal {
private String name;
private int age;
public abstract void eat();
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;
}
}
package com.ffyc.bcms.demo3;
public interface A {
void a();
}
package com.ffyc.bcms.demo3;
public interface B {
void b();
}
package com.ffyc.bcms.demo3;
public interface C {
void c();
}
1、接口不能实例化对象
2、一个接口可以继承多个接口
public interface MyInterface extends A,B,C{
}
3、一个类可以实现多个接口(一个类只能直接继承一个类)
package com.ffyc.bcms.demo3;
public class Dog extends Animal implements MyInterface,A{
@Override
public void eat() {
}
@Override
public void a() {
}
@Override
public void b() {
}
@Override
public void c() {
}
}
4、一个接口可以被多个类实现
package com.ffyc.bcms.demo3;
public class Cat implements MyInterface{
@Override
public void a() {
}
@Override
public void b() {
}
@Override
public void c() {
}
}
5、接口与实现类之间存在多态性-一个接口可以表示拥有此接口功能的所有类型(一个类可以表示其所有子类的对象)
package com.ffyc.bcms.demo3;
public class Test {
public static void main(String[] args) {
MyInterface myInterface=new Cat();
MyInterface myInterface1=new Dog();
}
}
6、当类实现接口的时候,类必须要实现接口中所有的抽象方法,否则,该类必须声明为抽象的类
四、具体类、抽象类、接口在程序设计时的使用场景
具体类(成员方法、成员变量、构造方法)
抽象类(成员方法、成员变量、构造方法、抽象方法)
接口(静态常量、抽象方法、静态方法、默认方法)
1、在程序设计时
(1)只定义功能,用接口
(2)不定义功能,用具体类
(3)既定义功能,又需要成员变量或成员方法或构造方法时,用抽象类
2、使用场景实例
package com.ffyc.bcms.demo4;
public abstract class Animal {
/*定义功能,要有成员变量,定义为抽象类*/
private String name;
private int age;
public abstract void eat();// 子类都要具备这个功能,定义为抽象方法
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;
}
}
package com.ffyc.bcms.demo4;
/*不定义功能,定义为具体类*/
public class Dog extends Animal implements Run{
private String type;// 狗特有的属性
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public void run() {
System.out.println("狗在地上跑步");
}
}
package com.ffyc.bcms.demo4;
public class Fish extends Animal implements Swim,Fly{
@Override
public void eat() {
System.out.println("鱼吃饲料");
}
@Override
public void swim() {
System.out.println("鱼在水里游泳");
}
@Override
public void fly() {
System.out.println("鱼在天上飞");
}
}
package com.ffyc.bcms.demo4;
public class Bird extends Animal implements Fly{
@Override
public void eat() {
System.out.println("鸟吃虫子");
}
@Override
public void fly() {
System.out.println("鸟儿在天上飞");
}
}
package com.ffyc.bcms.demo4;
/*只定义功能,定义为接口*/
public interface Run {
void run();
}
package com.ffyc.bcms.demo4;
public interface Swim {
void swim();
}
package com.ffyc.bcms.demo4;
public interface Fly {
void fly();
}
package com.ffyc.bcms.demo4;
import com.sun.org.apache.bcel.internal.generic.INSTANCEOF;
public class Test {
public static void main(String[] args) {
Person person=new Person();
/*人喂动物*/
Animal dog=new Dog();
Animal fish=new Fish();
Animal bird=new Bird();
person.feedAnimal(dog);
person.feedAnimal(bird);
person.feedAnimal(fish);
/*人观察会飞的动物*/
Fly bird1=new Bird();
Fly fish1=new Fish();
person.seeFlyAnimal(bird1);
person.seeFlyAnimal(fish1);
}
}