【Java SE】(九)抽象类和接口

一、抽象类

1.1 什么是抽象类

概念:如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
例如:假设有两种具体的水果(苹果(Apple类)和香蕉(Banana类)且都继承水果(Fruits)这个类,在水果类中有一个colour的方法,我们都知道子类继承父类需要重写子类中的方法,但是不同的水果的颜色不同,所以水果类中colour方法无法具体实现,但是苹果和香蕉这两个类是一种具体的水果,所以它们的colour方法能够具体实现),因此我们就可以把水果(fruits类)设计为**“抽象类”**。
在这里插入图片描述
我们可以发现在上图中国Frutis类中的colour()方法中并没有什么实际的行动内容,在java中我们可以把这一类方法设置为抽象方法,包含抽象方法的类我们叫做“抽象类”。


1.2 抽象类的语法

Java中被abstract修饰的类叫抽象类,被abstract修饰的方法叫抽象方法且抽象方法且不用给出具体的实现体。

// 抽象类即被abstract修饰的类
public abstract class Fruits {
// 抽象方法即被abstract修饰的方法,不用给出具体的方法体
abstract public void colour(); //颜色
abstract void shape();//形状

注意:抽象类也是类,和普通的类一样内部可以有普通方法和属性以及构造方法,但是不能进行实例化。


1.3 抽象类的特性

  1. 抽象类不能实例化对象,即new 抽象类();
  2. 抽象方法的访问权限不能是private私有的,且抽象方法没有加访问限定符时默认为public;
  3. 抽象类和抽象方法由于要被子类重写,所以不能被final和static修饰;
  4. 抽象类的实现必须要被继承,且抽象类中不一定有抽象方法,但如果这个方法是抽象方法,那么这个包含抽象方法的类一定是抽象类;
  5. 一个普通的类继承了抽象类,那么必须重写这个抽象类中的所有抽象方法,但如果一个抽象类继承一个抽象类,那么这个抽象类可以不用重写被继承的抽象类的抽象方法;
    抽象类的作用抽象类的使用如我们1.1举例,实际工作是由子类完成,而父类并没有实际性工作,它的作用就是为了让我们在今后使用代码时出现错误使用到父类了,能够尽早发现及时纠正。

二 、接口

2.1 接口的概念

接口是一种行为的规范和标准,Java中可以把接口看成多个类的公共规范,是一种引用新型数据类型。


2.2 接口的语法

接口的语法和定义类的语法基本相同,只需将定义类中的关键字class改成关键字interface,即定义了一个接口。

//用关键字interface定义一个接口
public interface 接口名称{
// 抽象方法
public abstract void method1(); // public abstract 是固定搭配,可以不写
void method2();
}

2.3 接口的特性

  1. 使用接口必须使用关键字interface修饰,接口也不能实例化, 即new 接口;
  2. 接口中不能有静态代码块和构造方法;
  3. 接口中的成员变量默认的访问权限是public static final,即静态常量;
  4. 接口中的成员方法只能是抽象方法, 默认是public abstract ;
  5. 想要具体实现接口当中的方法需要用到关键字default来修饰;但重写接口中的方法时却不能使用default修饰;且在接口中的静态方法可以具体实现;
  6. 类实现接口之间使用implement实现,一个普通的类可以通过implement来实现这个接口,且一个类既可以继承抽象类,还同时连接多个接口,使用逗号来分割每个接口;
  7. 如果类中没有实现接口中的所有抽象方法,那么这个类必须设置为抽象类。

2.4 接口之间的继承

Java中类和类之间只能为单继承,但是一个类却可以实现多个接口,并且接口和接口之间也可以多继承,因此解决多继承问题。
在这里插入图片描述


2.5 抽象类和接口的区别

核心区别

  1. 抽象类可以有普通方法和普通字段,并且这些普通方法和字段能够被子类直接使用,不需要重写;
  2. 而接口中不能包含普通方法,子类必须重写父类所有的抽象方法。

三、接口的浅拷贝和深拷贝

3.1 Object类

object类是Java中默认的一个类,除了object类,Java中所有的类都是继承这个类的,也就是说Object类是Java中所有类的父类,Java中所有类的对象都可以使用object引用接收。

  1. Object接收所有类对象
  2. 获取对象信息在这里插入图片描述

3.2 浅拷贝

Java中的很有用的一个接口——Cloneable(是一个浅拷贝),Object类中存在一个clone()的方法,这个方法在调用时必须先实现Cloneable接口, 才能被合法调用 , 否则就会抛出 CloneNotSupportedException 异常,这个方法的调用可以创建一个对象的 “拷贝”,从而实现浅拷贝。

class Fraction{
    public double a = 99;
}
// 实现Cloneable接口并重写clone()方法
class Student implements Cloneable{  
    public Fraction fraction = new Fraction();

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Demo1 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student();
        Student student2 = (Student) student1.clone(); //用clone()方法创建一个对象的拷贝
        System.out.println("student1修改之前的分数");
        System.out.println(student1.fraction.a);
        System.out.println(student2.fraction.a);
        student2.fraction.a = 59;
        System.out.println("student1修改后的分数");
        System.out.println(student1.fraction.a);
        System.out.println(student2.fraction.a);
    }
}

运行结果可知
运行结果如下


3.3 深拷贝

在认识了浅拷贝之后我们就要思考什么是深拷贝呢?
深拷贝不是某个方法是深拷贝,而是在代码的层次上进行的,需要从代码的实现上来看待的,意思就是若想达到深拷贝,那么在每个对象中,如果有引用这个对象的引用所指向的其他对象,那么这个所指向的其他对象也要进行拷贝。

class Fraction implements Cloneable{  //由深拷贝可知这个对象也需要进行clone拷贝,所以也需要实现Cloneable接口
    public double a = 99;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Student implements Cloneable{
    public Fraction fraction = new Fraction();

    @Override
    protected Object clone() throws CloneNotSupportedException {
//        return super.clone();
        Student student = (Student) super.clone(); 
        student.fraction = (Fraction) this.fraction.clone(); //每个对象的引用所指向的其他对象的也需要进行拷贝
        return student;
    }
}
public class Demo1 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student1 = new Student();
        Student student2 = (Student)student1.clone();
        System.out.println("student1修改之前的分数");
        System.out.println(student1.fraction.a);
        System.out.println(student2.fraction.a);
        student2.fraction.a = 59;
        System.out.println("student1修改后的分数");
        System.out.println(student1.fraction.a);
        System.out.println(student2.fraction.a);

    }
}

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


四、总结

以上就是今天所学习的内容,主要学习了抽象类和接口的内容,认识到了抽象类和接口的区别,并且运用接口能够解决多继承的问题,也了解到了浅拷贝和深拷贝的区别,还能够使用代码理解这些内容,但掌握的还很初步,希望今后能够多多运用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@澄夏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值