Java中的接口

接口是抽象类的更进一步,抽象类中还可以包含非抽象方法, 和字段,而接口中包含的方法都是抽象方法, 字段只能包含静态常量

语法规则

interface IShape {
void draw();
}
class Cycle implements IShape {
@Override
public void draw() {
System.out.println("○");
}
}
public class Test {
public static void main(String[] args) {
IShape shape = new Rect();
shape.draw();
}
}

1、使用 interface 定义一个接口
2、接口中的方法一定是抽象方法, 因此可以省略 abstract
3、接口中的方法一定是 public, 因此可以省略 public
4、Cycle 使用 implements 继承接口,此时表达的含义不再是 “扩展”, 而是 “实现”
5、在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例
6、接口不能单独被实例化

接口中只能包含抽象方法. 对于字段来说, 接口中只能包含静态常量(final static)

interface IShape {
void draw();
public static final int num = 10;
}

其中的 public, static, final 的关键字都可以省略. 省略后的 num 仍然表示 public 的静态常量

实现多个接口

有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的,然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果
例:

class Animal {
protected String name;
public Animal(String name) {
this.name = name;
}
}
interface IFlying {
void fly();
}
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
class Cat extends Animal implements IRunning {
public Cat(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在用四条腿跑");
}
}
class Fish extends Animal implements ISwimming {
public Fish(String name) {
super(name);
}
@Override
public void swim() {
System.out.println(this.name + "正在用尾巴游泳");
}
}
class Frog extends Animal implements IRunning, ISwimming {
public Frog(String name) {
super(name);
}
@Override
public void run() {
System.out.println(this.name + "正在往前跳");
}
@Override
public void swim() {
System.out.println(this.name + "正在蹬腿游泳");
}
}

IDEA 中使用 ctrl + i 快速实现接口

class Duck extends Animal implements IRunning, ISwimming, 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 + "正在漂在水上");
}
}

接口间的继承

接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字

interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}

Cloneable 接口和深拷贝

Java 中内置了一些很有用的接口, Clonable 就是其中之一,Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”,但是要想合法调用 clone 方法, 必须要先实现 Cloneable 接口, 否则就会抛出CloneNotSupportedException 异常

class Animal implements Cloneable {
private String name;
@Override
public Animal clone() {
Animal o = null;
try {
o = (Animal)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
public class Test {
public static void main(String[] args) {
Animal animal = new Animal();
Animal animal2 = animal.clone();
System.out.println(animal == animal2);
}
}
// 输出结果
// false

浅拷贝 VS 深拷贝
Cloneable 拷贝出的对象是一份 “浅拷贝”
观察以下代码:

public class Test {
static class A implements Cloneable {
public int num = 0;
@Override
public A clone() throws CloneNotSupportedException {
return (A)super.clone();
}
}
static class B implements Cloneable {
public A a = new A();
@Override
public B clone() throws CloneNotSupportedException {
return (B)super.clone();
}
}
public static void main(String[] args) throws CloneNotSupportedException {
B b = new B();
B b2 = b.clone();
b.a.num = 10;
System.out.println(b2.a.num);
}
}
// 执行结果
10

通过 clone 拷贝出的 b 对象只是拷贝了 b 自身, 而没有拷贝内部包含的 a 对象. 此时 b 和 b2 中包含的 a 引用仍然是指向同一个对象. 此时修改一边, 另一边也会发生改变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值