1.接口的概念
比如 笔记本上的usb口,电源插座
接口是多个类的公共规范,是一种引用数据类型
2.语法规则
将 class 关键字换成 interface 关键字,就定义了一个接口
public interface 接口名称{
}
接口名称的规则:
- 创建接口时,接口名称以大写字母 I 开头
- 接口命名一般使用“形容词"词性的单词
- 接口中的方法和属性不要加任何修饰符好,保持代码简洁
3.接口使用
Computer.java
package Day20210926;
public class Computer {
private String name;
private String price;
public void powerOn(){
System.out.println("打开笔记电脑");
}
public void powerOff(){
System.out.println("关闭笔记本电脑");
}
public void usbDevice(IUSB usb) {
if (null == usb) {
System.out.println("没有设备连接");
return;
}
usb.openDevice();
if(usb instanceof Mouse){
Mouse mouse = (Mouse) usb;
mouse.click();
}else if(usb instanceof KeyBoard){
KeyBoard keyboard = (KeyBoard) usb;
}else{
System.out.println("无法识别设备");
}
usb.closeDevice();
}
}
IUSB.java(接口)
package Day20210926;
public interface IUSB {
void openDevice();
void closeDevice();
}
TestComputer.java
package Day20210926;
public class TestComputer {
public static void main(String[] args) {
Computer com = new Computer();
com.powerOn();
com.usbDevice(new Mouse());
com.usbDevice(new KeyBoard() {
});
com.powerOff();
}
}
Mouse.java
package Day20210926;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
public class Mouse implements IUSB{
@Override
public void openDevice() {
System.out.println("打开鼠标设备");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标设备");
}
public void click(){
System.out.println("鼠标点击");
}
}
KeyBoard.java
package Day20210926;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
public abstract class KeyBoard implements IUSB{
@Override
public void openDevice() {
System.out.println("打开键盘");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘");
}
public void input(){
System.out.println("键盘输入");
}
}
4.接口特性
- 接口类型是一种引用类型,但是不能直接new接口的实例
public class TestShape{
public static void main(String[] args){
IShape shape = new IShape();
}
}
- 接口中每一个方法都是public的抽象方法,接口中的方法会被隐式的指定为 public abstract,其他修饰会报错
public class TestShape{
public double calcArea();
private double calcPerimeter();
}
- 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final
public interface IShape {
public double calcArea();
public double calcPerimeter();
double PI = 3.14;
}
public class TestShape {
public static void main(String[] args) {
IShape shape = new Rectangle();
System.out.println(Rectangle.PI);
System.out.println(IShape.PI);
}
}
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现
public interface IShape {
public double calcArea();
double calcPerimeter(){
return 0;
}
}
- 接口虽然不是类,但是接口编译后完成字节码文件的后缀格式也是**.class**
- 重写接口中方法时,不能使用default访问权限修饰
interface IShape {
abstract void draw() ;
}
class Rect implements IShape {
void draw() {
System.out.println("□") ;
}
}
- 接口中不能由静态代码块和构造方法
5.实现多个接口
ISport(接口)
package JieKou;
public interface ISport {
interface IFlying{
void fly();
}
interface IRunning{
void run();
}
interface ISwimming{
void swim();
}
}
Cat.java
package JieKou;
public class Cat extends Animal implements ISport.IRunning {
public Cat(String name){
super(name);
}
@Override
public void run() {
System.out.println(this.name + "用四条腿跑");
}
}
Fish.java
package JieKou;
public class Fish extends Animal implements ISport.ISwimming {
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(this.name + "正在用尾巴游泳");
}
}
Frog.java
package JieKou;
public class Frog extends Animal implements ISport.ISwimming, ISport.IRunning {
public Frog(String name){
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在往前跳");
}
@Override
public void swim() {
System.out.println(this.name + "正在游泳");
}
}
Duck.java
package JieKou;
public class Duck extends Animal implements ISport.ISwimming, ISport.IRunning, ISport.IFlying {
public Duck(String name){
super(name);
}
@Override
public void fly() {
System.out.println(this.name + "正在挥动翅膀飞");
}
@Override
public void run() {
System.out.println(this.name + "正在跑");
}
@Override
public void swim() {
System.out.println(this.name + "正在游泳");
}
}
注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。 提示, IDEA 中使用 ctrl + i 快速实现接口 一个类继承一个父类, 同时实现多种接口.
6.接口间的继承
在Java中,类和类之间是单继承的,即一个类只能有一个父类,但是一个类与接口之间是多实现的,即一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的。
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
.......
}
接口间的继承相当于把多个接口合并在一起.
7.深拷贝和浅拷贝
浅拷贝:在拷贝过程中,并没有将对象中的内容拷贝一份,而是将对象的引用变量(即s1和s2)中的内容拷贝一份.最终导致的后果就是两个引用变量实际引用同一份对象
public static void main(String[] args){
Student s1 = new Student(name: "张三",score:90);
Student s2 = s1;
System.out.println(s1 == s2);
}
深拷贝:将实际对象中的内容拷贝一份,形成一个新的对象 注意:深拷贝和浅拷贝是针对于自定义类型来说的 ,对于基本类型不存在深浅拷贝这么一说。
8.接口与类相似点
- 一个接口有多个方法
- 接口文件保存在.Java结尾的文件中,文件名使用接口名
- 接口的字节码文件保存在 .class 结尾的文件中
- 接口相应的字节码文件必须在于包名称相匹配的目录结构中
9.接口与类的区别
1.接口不能用于实例化对象。 2.接口没有构造方法。 3.接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰4.的非抽象方法。 5.接口不能包含成员变量,除了 static 和 final 变量。 6.接口不是被类继承了,而是要被类实现。 7.接口支持多继承。
10.接口和抽象类的区别
- 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
- 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
- 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
- 一个类只能继承一个抽象类,而一个类却可以实现多个接口。
注:JDK 1.8 以后,接口里可以有静态方法和方法体了。
注:JDK 1.8 以后,接口允许包含具体实现的方法,该方法称为"默认方法",默认方法使用 default 关键字修饰。更多内容可参考 Java 8 默认方法。
注:JDK 1.9 以后,允许将方法定义为 private,使得某些复用的代码不会把方法暴露出去。更多内容可参考 Java 9 私有接口方法。
|