接口(interface)
是一个抽象类型,机制的抽象,接口一般以interface来声明,一个类通过实现(implements )接口的方式实现所有接口中的抽象概念
首先要明确,接口不是类,只是对实现它的类的一组需求
&接口与类的相似点
- 一个接口可以有多个方法
- 接口相应的字节码文件必须在与包名称匹配的目录结构中
&接口与类的不同点:
- 接口不能用来实例化对象
- 接口没有构造方法
- 接口中所有的方法都是抽象方法
- 接口中只有static和final变量,不过一般都没有
- 接口不是被类继承了,是被类实现了
- 接口支持多继承(类不支持)
接口特性:
- 接口中每一个方法都是隐式抽象的,接口中的方法被隐式的指定为public
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变
量只能是public static final 类型的 - 接口中不能含有静态代码块以及静态方法,而抽象类可以,所以接口更为抽象(然而后来就被改了)
- 一个类只能实现一个抽象类,但是可以实现多个接口
注:JDK1.8以后重复1,接口里可以有静态方法和方法体了
下面例子中就有一个默认方法(default)
()()()()()()()()()()
接口中的静态方法和默认方法
++++++++++++++++++++++++++++++++++++++++++++++++
举个栗子时间
定义一个抽象类People,普通子类student,俩接口。
子类Student继承父类People,并且实现接口Study,Write。
package demo;
创建一个抽象类people
abstract class People{
超类属性私有化
private int age;
private String name;
提供超类构造器
public People(String name,int age){
this.name=name;
this.age=age;
}
提供获取和设置属性的getter()/setter()方法
public String getName(){return name;}
public int getAge(){return age;}
public void setName(String name){this.name=name;}
public void setAge(int age){this.age=age;
}
提供一个抽象方法
public abstract void talk();
}
定义一个接口
interface Study{
设置课程数量为3
int COURSENUM = 3;
构建一个默认方法
default void stu (){
System.out.println("学生需要学习"+COURSENUM+"门课程");
}
}
再定义一个接口
interface Write {
定义一个抽象方法
void print();
}
子类继承People。实现接口Study.Write
class Student extends People implements Study ,Write{
通过super关键字来调用超类构造器
public Student(String name,int age){
super(name,age);
}
实现超类的抽象方法
public void print(){
System.out.println("我的名字叫"+this.getName)
}
实现Write接口里面的抽象方法
public vodi print(){
System.out.println("学生学习");
}
}
public class InterfaceDemo{
public static void main(String []args){
构建Student对象
Student student = new Student ("dodo",22);
调用父类的抽象方法
student.talk();
调用接口Write中的抽象方法
student.print();
调用接口Study中的默认方法
student.stu();
}
}
}
一般情况下,接口可以提供多重继承的大多数好处,同时还能避免多重继承的复杂性和低效性。
————————————————————————————
接口制订规范的实例
电脑可以和各种设备连接,提供统一的USB接口,
其他设备只能通过USB接口与电脑相连
interface USB
{
public void work();
对于适配的USB设备将会进行工作
}
class Print implements USB
{
public void work()
{
System.out.println("打印机使用USB接口,开始工作");
}
}
class Flash implements USB
{
public void work()
{
System.out.println("U盘使用USB接口,开始工作");
}
}
class Computer
{
public void plugin(USB usb)
{
按设定好的方式进行工作
usb.work();
}
public class InterfaceStandarads
{
public static void main(String 【】args)
{
Computer computer = new Computer();
computer.plugin(new Print());
computer.plugin(new Flash());
}
}
}
案例中怎么架构起整个规范的?
我们可以看到,对于USB接口,Computer里提供了接受usb实现类对象的参数。打印机和U盘两个类可以很轻松的向上转型成为参数,传入方法中。
也就是说两台机器都遵守了usb的规范且传进电脑后都能实现自己独特的功能(这也是接口规范被设置出来的过程)
———————————————————————————
%%%%
【接口类的优秀实践】(工厂模式)
设计模式中的工厂模式
之前已经对静态工厂方法有所了解
什么是工厂模式?工厂模式是为了解耦:把对象的创建和使用的过程分开。A调用B,只调用B的方法,B的产生交给一个工厂类。
工厂模式可以降低代码重复。如果创建对象B的过程都很复杂,而且在很多地方都会用到,那么可以统一进工厂管理。
好处:维护容易(统一),容易将所有对B的调用变成对C的调用
(这可能也是缺点??这个倒不是很清楚)
案例来啦!
package demo;
import java.util.Scanner;
interface Fruit //定义一个水果标准
{
public abstract void eat();
}
class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
class factory水果工厂!
{
public static Fruit getInstance(String className) //返回值是Fruit的子类
{
if("apple".equals(className))
{
return new Apple();
}
else if("orange".equals(className))
{
return new Orange();
}
else
{
return null;
}
}
}
public class ComplexFactory {
public static void main(String[] args)
{
System.out.println("请输入水果的英文名:");
Scanner sc = new Scanner(System.in);
String ans = sc.nextLine();
Fruit f = factory.getInstance(ans); //初始化参数
f.eat();
sc.close();
}
}
接口抽象类的设计思想区别
抽象类是继承关系,父子在概念上应该保持相同,接口则不一样,如果使用接口则不需要概念相同,接口只是一个规则约束
——————————————————
如何回答面试“接口抽象类区别”
接口和抽象类是支持抽象定义的两个机制。
接口是公开的,不能私有的方法或变量。
抽象类是可以私有方法和变量的,并且只有声明为抽象的方法木有方法体。
不同:
1接口只有定义,不能有方法实现,java1.8可以默认default方法体,而抽象类中是允许有方法体的
2实现的关键字不同,实现接口的是implements,继承的是
extends 。
定义抽象类的是abstract接口interface
3接口成员默认为public static final,必须赋初值,不能被修改
抽象类中成员变量默认default,可以在子类中重新定义赋值,抽象方法不能被private,static,synchronized和native等修饰;
4 接口被用于常用的功能以便于日后维护,抽象类适合充当公共类,不适用于日后进行代码修改
- 功能需要积累用抽象类,不需要积累用接口!@
——————————————————————————
接口与回调
回调(callback)是一种常见的程序设计模式,在这种模式中,可以指定某个特定事件发生时应该采取的动作。 例如,按下鼠标或者选择某个菜单项时,你可能希望完成某个特定的动作。不过,由于至此还没有介绍如何使用用户界面,所以讨论一种与此类似但更简单的情况。
工具:Timer类
package 接口与回调预习;
import java.awt.*;
import java.awt.event.*;
import java.time.*;
import javax.swing.*;
public class tryCallBack {
//工具:Timer类
public static void main(String[] args) {
TimePrinter listener = new TimePrinter();
Timer time = new Timer(1000,listener);
time.start();
JOptionPane.showMessageDialog(null, "Quit program");
System.exit(0);
}
}
class TimePrinter implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("At the tone ,the time is" + Instant.ofEpochMilli(event.getWhen()));
Toolkit.getDefaultToolkit().beep();
}
}
——————————————
p235起到242
对象克隆:
我们知道,创建一个对象的副本实际上是创建了对象的一个引用,对任何一个引用做修改会对所有的进行操作
如果希望拷贝一个和本对象当前·状态相同的对象,而且不会互相影响,要求会比较高,等真正需要时扎起深入学习。