Java面试基础篇之java基础语法之七:抽象类与接口,高级架构师软考

}

使用 interface 定义一个接口

接口中的方法一定是抽象方法, 因此可以省略 abstract

接口中的方法一定是 public, 因此可以省略 public

Cycle 使用 implements 继承接口. 此时表达的含义不再是 “扩展”, 而是 “实现”

在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例

接口不能单独被实例化

扩展(extends) vs 实现(implements) 扩展指的是当前已经有一定的功能了, 进一步扩充功能. 实现指的是当前啥都没有, 需要从头构造出来

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

interface IShape {

void draw();

public static final int num = 10;

}

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

提示:

1. 我们创建接口的时候, 接口的命名一般以大写字母 I 开头.

2. 接口的命名一般使用 “形容词” 词性的单词.

3. 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性

实现多个接口

有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的. 然而 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();

}

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

下来我们创建几个具体的动物

猫, 是会跑的

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 + “正在蹬腿游泳”);

}

}

还有一种神奇的动物, 水陆空三栖, 叫做 “鸭子”

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 + “正在漂在水上”);

}

}

上面的代码展示了 Java 面向对象编程中最常见的用法:

一个类继承一个父类, 同时实现多种接口.

继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性

这样设计有什么好处呢? 时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而 只关注某个类是否具备某种能力

接口间的继承

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

interface IRunning {

void run();

}

interface ISwimming {

void swim();

}

// 两栖的动物, 既能跑, 也能游

interface IAmphibious extends IRunning, ISwimming {

}

class Frog implements IAmphibious {

}

Clonable 接口和深拷贝

Java 中内置了一些很有用的接口, Clonable 就是其中之一

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”

但是要想合法调用 clone 方法, 必须要先 实现 Clonable 接口, 否则就会抛出 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 引用仍 然是指向同一个对象. 此时修改一边, 另一边也会发生改变

总结

==

上一篇:maven5 依赖域scope


下一篇:maven scope