接口相当于特殊的抽象类,定义方式、组成部分与抽象类类似。
微观概念:接口是一种能力。
宏观概念:接口是标准
为什么需要接口: Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。接口支持多实现,可为类扩充多种能力。
注意点:
//创建一个接口代码
interface MyInterface{
//创建公开的静态常量
//public static final String NAME="接口1";
//public static final默认包含,可以省略
String NAME="接口1";
//创建公开的抽象方法
//public abstract void method();
//public abstract默认包含,可以省略
void method();
}
接口无法实例化对象,下面这条语句是错误的。
MyInterface myInterface = new MyInterface();
但是接口可以创建引用,想要实现接口需要一个实现类,实现类通过关键字implements继承接口。
//对上面建立的接口创建实现类,实现类中必须对接口中的方法重写
public class Impl implements MyInterface{
@Override
public void method() {
System.out.println("method");
}
}
/*测试类
public class TestInterface {
public static void main(String[] args) {
MyInterface myInterface=new Impl();//父类引用指向子类对象
myInterface.method();
}
}
*/
接下来看一个使用接口的例子:
创建一个Person类,有姓名,年龄两种属性,有吃和睡两种方法,Person类代码如下:
public class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(name+"吃东西...");
}
public void sleep(){
System.out.println(name+"睡觉...");
}
}
我希望对Person这个类扩充两种能力,飞和喷火,因此建立两个接口来代表这两种能力:
//喷火
public interface Fireable {
void fire();
}
//飞
public interface Flyable {
void fly();
}
创建了这两个接口以后,我需要人来实现这两种能力,因此需要Person类使用implements关键字来实现这两种能力,并在Person类中实现这两个接口的方法重写,现在Person类如下:
public class Person implements Flyable,Fireable{//多继承
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println(name+"吃东西...");
}
public void sleep(){
System.out.println(name+"睡觉...");
}
@Override//方法重写
public void fly() {
System.out.println(name+"飞...");
}
@Override//方法重写
public void fire() {
System.out.println(name+"喷火...");
}
}
目前为止,Person类已经实现了两个接口,获得了飞和喷火的能力,写一个测试类看一下结果:
public class TestInterface {
public static void main(String[] args) {
Person person=new Person("小明",22);//创建对象来实现方法调用
person.fly();
person.fire();
System.out.println("========多态=========");//使用多态来实现方法调用
Flyable flyable=new Person("小张",22);
flyable.fly();//flyable只能调用Flyable接口中的方法,不能调用Person类中的其他方法
Fireable fireable=new Person("小红",23);
fireable.fire();
}
}
实现接口时要注意:
任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
实现接口中的抽象方法时,访问修饰符必须是public。
同父类一样,接口也可声明为引用,并指向实现类对象。但是要注意:1.仅可调用接口中所声明的方法,不可调用实现类中独有的方法;2.可强转回实现类本身类型,进行独有方法调用。3.通过接口可调用Object中的公开方法。
我们来看这样一个例子,有一个动物类Animal:
//Animal类有两个方法,吃和睡
public abstract class Animal {
public void eat(){
System.out.println("吃");
}
public void sleep(){
System.out.println("睡");
}
}
同时,有一个Dog类继承了Animal类和两个接口:
//接口1,跑
public interface Runnable {
void run();
}
//接口2.游泳
public interface Swimable {
void swim();
}
//Dog类继承了Animal类和两个接口:
//同时继承父类和接口时,父类要写在前
public class Dog extends Animal implements Runnable,Swimable{
public void shout(){
System.out.println("狗狗开始叫...");
}
@Override
public void run() {
System.out.println("狗狗跑步");
}
@Override
public void swim() {
System.out.println("狗狗游泳");
}
}
这时,写一个测试类:
public class TestInterface {
public static void main(String[] args) {
Dog dog=new Dog();
Animal a=dog;//父类引用指向子类对象
Runnable r=dog;//父类引用指向子类对象
Swimable s=dog;//父类引用指向子类对象
dog.run();//dog可以调用Dog类内的所有方法
dog.shout();
dog.swim();
dog.eat();
dog.sleep();
a.eat();//a只能调用Animal类的方法
a.sleep();
r.run();//r只能调用接口Runable中的方法
s.swim();////s只能调用接口Swimable中的方法
}
}
从上面这个例子可以看到,多种不同类型的引用指向同一个对象时,表示看待对象的视角不同。
Dog myDog: 将狗当狗看
Animal a:将狗当动物看
Runnable r:将狗当会跑的东西看
Swimmable s:将狗当会游的东西看
不同引用所能看到的对象范围不同,只能调用自身类型中所声明的部分
常量接口将多个常用于表示状态或固定值的变量,以静态常量的形式定义在
接口中统一管理, 提高代码可读性。
//常量接口,只有公开的静态常量
public interface ConstInterface {
String CONST1="aaa";
String CONST2="bbb";
String CONST3="ccc";
}
静态常量的访问:
public class TestConstInterface {
public static void main(String[] args) {
if(ConstInterface.CONST1.equals("aaa")){
System.out.println("123");
}
}
}
标记接口中没有包含任意成员,仅仅用作标记。
public interface Serializable {
}
public interface Cloneable {
}
接口回调:先有接口的使用者,后有接口的实现者。
现有一个Usb接口:
public interface Usb {
void Service();
}
有一台电脑有三个Usb接口:
public class Computer {
Usb usb1;
Usb usb2;
Usb usb3;
public void run(){
System.out.println("电脑开始工作...");
if (usb1!=null){
usb1.Service();
}
if (usb2!=null){
usb2.Service();
}
if (usb3!=null){
usb3.Service();
}
}
}
此时,三个Usb接口都为空,但是电脑可以正常工作,为了使用这三个接口,定义三个实现类:
//U盘类
public class Upan implements Usb {
@Override
public void Service() {
System.out.println("U盘连接电脑成功,开始工作...");
}
}
//风扇类
public class Fan implements Usb{
@Override
public void Service() {
System.out.println("风扇连接电脑成功,开始工作...");
}
}
//鼠标类
public class Mouse implements Usb {
@Override
public void Service() {
System.out.println("鼠标连接电脑成功,开始工作...");
}
}
写一个测试类:
//测试类
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
Usb mouse=new Mouse();
Usb upan=new Upan();
Usb fan=new Fan();
computer.usb1=mouse;
computer.usb2=upan;
computer.usb3=fan;
computer.run();
}
}
我们可以看到,在测试类中,不写下面六句语句,电脑仍可正常运行,这就叫先有接口的使用者(电脑),后有接口的实现者。
Usb mouse=new Mouse();
Usb upan=new Upan();
Usb fan=new Fan();
computer.usb1=mouse;
computer.usb2=upan;
computer.usb3=fan;
接口的好处:
程序的耦合度降低。
更自然的使用多态。
设计与实现完全分离。
更容易搭建程序框架。
更容易更换具体实现。
什么是接口:
微观:接口是一种能力和约定。
宏观:接口是一种标准。
接口与类的异同:
没有构造方法,仅可定义公开静态常量与公开抽象方法。
接口的应用
Java为单继承, 当父类的方法种类无法满足子类需求时,可实现接口扩充子类能力。
接口的规范
什么是常量接口
将多个常用于表示状态或固定值的变量,以静态常量的形式定义在接口中统一管理。
什么是接口回调
先有接口的使用者,后有接口的实现者。
原文:https://www.cnblogs.com/Ng3061851/p/14404189.html