抽象类、接口

1.抽象类 abstract

抽象类中有什么?

  • 抽象类和普通类相比,大部分是一样的,可以有属性、方法、静态成员,可以被继承,也可以继承别的类。

  • 抽象类和普通类最大的区别,抽象类中可以有抽象方法。抽象方法只有方法声明,没有方法体。
    eg: public int abstractFountion(); //抽象方法 无方法体

  • 注意1:抽象类不能实例化对象

  • 注意2:一个类继承自一个抽象类,如果没有全部实现父类中的抽象方法,则此类应继续定义为抽象类。

为什么要存在抽象类?

  • 从设计角度,有些类不应该被实例化,就可以设计为抽象类。
  • 抽象类和抽象方法存在,就是为了被其他类继承,重写它的抽象方法。实际使用抽象类的时候,和继承、多态语法密切相关。
  • 抽象类是一种语法上的要求,是一种校验机制,为了降低代码出错概率。

解释: 一个抽象类,去掉 abstract ,变成普通类,代码也是可以运行的,结果没有差异。加上 abstract 多一重语法校验,防止在代码中不小心创建不应该被实例化的对象。

2.接口 interface

接口中有什么?

  • 抽象方法
  • 静态常量

注意:接口中的方法默认public abstract;常量默认 public static final

为什么要存在接口?

  • 在设计角度,接口存在的意义就是突破单继承的限制。
  • 接口比抽象类更严格一点。

注意:接口也可以继承多个接口。

public interface  接口  extends 接口一,接口二,……{}

实例

Comparable接口

如果不复写 compareTo 方法,直接Arrays.sort(boy);运行出错抛出异常

sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Boy 类型的对象。

package sort;

public class Boy implements Comparable<Boy> {
    private String name;
    private int money;
    private int faceValue;

    public Boy(String name, int money, int faceValue) {
        this.name = name;
        this.money = money;
        this.faceValue = faceValue;
    }

    @Override
    public String toString() {
        return "Boy{" +
                "name='" + name + '\'' +
                ", money=" + money +
                ", faceValue=" + faceValue +
                '}'+"\r\n";
    }

    @Override
    public int compareTo(Boy o) {
        // 比较 this 和 other
        // 如果是 this 在 other 前面, 就应该返回 < 0
        // 如果是 this 在 other 后面, 就应该返回 > 0
        // 如果是 this 和 other 并列, 就应该返回 0
        if (this.money > o.money) {
            // this 在前
            return -1;
        }
        if (this.money < o.money) {
            // other 在前
            return 1;
        }
        // 钱一样多, 再比较脸
        if (this.faceValue > o.faceValue) {
            return -1;
        }
        if (this.faceValue < o.faceValue) {
            return 1;
        }
        // 钱和脸都一样的话, 两者就并列
        return 0;
    }
}
package sort;

import java.util.Arrays;

public class Test {
    public static void main(String[] args) {
        Boy[] boys = {
                new Boy("吴彦祖", 100, 100),
                new Boy("肖战", 50, 80),
                new Boy("胡歌", 100, 120),
                new Boy("巨魔战将", 20, 20)
        };

        // 编译出错, 1
        // 编译通过, 运行异常 2
        // 运行通过, 能排序出一个结果 3
        sort(boys);
        System.out.println(Arrays.toString(boys));
    }

    // 模拟实现以下 Arrays.sort
    // Comparable 本来带一个泛型参数. 这个参数也可以没有, 没有就表示 Object
    public static void sort(Comparable[] array) {
        for (int bound = 0; bound < array.length; bound++) {
            for (int cur = array.length - 1; cur > bound; cur--) {
                if (array[cur - 1].compareTo(array[cur]) > 0) {
                    // 如果前一个元素和后一个元素相比, 不符合排序要求, 就交换两个元素
                    Comparable tmp = array[cur - 1];
                    array[cur - 1] = array[cur];
                    array[cur] = tmp;
                }
            }
        }
    }
}

测试结果:
在这里插入图片描述

Cloneable 接口和深拷贝

Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “深拷贝”。 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出CloneNotSupportedException异常。

深拷贝:不仅仅拷贝引用。也要把实际的对象进行拷贝(对象对应的内存空间没有被重新复制一份)。
浅拷贝:只是拷贝了一个引用,实际的对象没有被拷贝。

class Animal implements Cloneable {
    public String name;
    public Animal(String name){
        this.name = name;
    }
    @Override
    public Animal clone() {
        Animal o = null;
        try {
            o = (Animal)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return o;
    }
}
class Test {
    public static void main(String[] args) {
        Animal animal = new Animal("老虎");
        System.out.println(animal.name);//老虎
        Animal animal2 = animal.clone();
        System.out.println(animal2.name);//老虎
        System.out.println(animal == animal2);//false
        // 说明调用 clone 方法之后, 得到了一个全新的 Animal 对象.
        // 这个过程称为 "深拷贝"
    }
}

运行结果:
在这里插入图片描述

3.接口和抽象类区别

共同点:体现了多态。

  • 区别1:
    抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写)。
    接口中只能有抽象方法、静态常量,不能包含普通方法, 子类必须重写所有的抽象方法。
  • 区别2:
    抽象类遵守 “单继承” 规则,一个类不能继承自多个普通类。
    接口遵守 “多继承” 规则,一个类可以同时实现多个接口。
    注意:public class Bird extends Aimal implements IFlying,IRuning{}
  • 区别3:
    在设计层面考虑,抽象类是行为的抽象,接口是动作的抽象。
  • 区别4:
    抽象方法只能申明,不能实现,抽象类是重构的结果,接口是设计的结果 。

小结:

区别抽象类( abstract )接口( interface )
结构组成普通类+抽象方法抽象方法+全局1常量
权限各种权限public
子类使用使用extends关键字继承抽象类使用implements关键字实现接口
关系一个抽象类可以实现若干接口接口不能继承抽象类,但是接口可以使用extends关键字继承多个父接口
子类权限一个子类只能继承一个抽象类一个子类可以实现多个父接口
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值