• 抽象类和接口


    目录

    前言:

    抽象类

    语法规则

    接口

    语法规则

    Cloneable接口

    Comparable接口

    深浅拷贝

    浅拷贝

    深拷贝

     小结:


    前言:

        在面向对象语言中,所有对象都是用类来描述,但并不是所有对象都是用类来描述的,如果一个类没有包含足够的信息去描述一个对象,这就是抽象类。

        接口是对一些共有的行为的一种规范,类只需要实现一些接口就可以实现属于自己的行为。

    抽象类

    语法规则

    1. abstract class A {
    2. abstract public void fun();
    3. int a;
    4. public void fun2() {
    5. System.out.println("bbbbb");
    6. }
    7. }
    8. class B extends A {
    9. public void fun() {
    10. System.out.println("aaaaa");
    11. }
    12. }

    abstract修饰抽象类

    注意:抽象类是没有足够的信息来描述一个对象,因此抽象类是不能实例化对象,最大的作用就是被类所继承。一般类继承抽象类是必须重写抽象类中抽象方法,除非是抽象类继承抽象类,但最终被一般类继承后还是得重写抽象类方法。由于抽象方法要被重写,所以不能被private,final,static修饰。抽象类也是类,所以它包含一般类应有的特性,比如也存在构造方法等等。

    接口

    语法规则

    1. interface A {
    2. void fun();
    3. public abstract void fun2();
    4. int a = 0;
    5. public static final int a2 = 0;
    6. }
    7. class B implements A {
    8. public void fun() {
    9. System.out.println("aaaaa");
    10. }
    11. public void fun2() {
    12. System.out.println("bbbbb");
    13. }
    14. }

    interface声明接口,implements实现接口

    注意:

    🎈接口就是规范行为,用来实现的,所以不能实例化对象。接口中只能包含抽象方法和常量,就算方法或者变量前什么都不写,默认被public abstract和public static final修饰。由于接口不是类,其中不能包含静态代码块,和构造方法。

    🎈在java中不支持多继承,但是一个类可以同时实现多个接口,对所有接口中抽象方法必须重写,否则就用抽象类实现。接口和接口之间是可以继承的,使用extends关键字,接口之间支持多继承

     Cloneable接口

    1. class Person0 implements Cloneable{
    2. int age;
    3. String name;
    4. public void fun() {
    5. System.out.println("aaaaa");
    6. }
    7. public Person0(int age, String name){
    8. this.age = age;
    9. this.name = name;
    10. }
    11. @Override
    12. protected Object clone() throws CloneNotSupportedException {
    13. return super.clone();
    14. }
    15. @Override
    16. public String toString() {
    17. return "Person0{" +
    18. "age=" + age +
    19. ", name='" + name + '\'' +
    20. '}';
    21. }
    22. }
    23. public class Test13 {
    24. public static void main(String[] args) throws CloneNotSupportedException{
    25. Person0 stu = new Person0(21,"www");
    26. Person0 stu2 = (Person0)stu.clone();
    27. System.out.println(stu);
    28. System.out.println(stu2);
    29. }
    30. }

     

    🤨所有没有继承类的类默认都继承了Object类

    🤨原码中Cloneable是一个空接口,其中没有任何的抽象方法,是由于在Object类中有clone方法,Cloneable的存在就是让我们清楚看见这个类实例化的对象是支持克隆的。所以我们只需要重写clone方法,然后去调用父类Object中clone方法。

    Comparable接口

    1. import java.util.Arrays;
    2. class Person0 implements Comparable{
    3. int age;
    4. String name;
    5. public void fun() {
    6. System.out.println("aaaaa");
    7. }
    8. public Person0(int age, String name) {
    9. this.age = age;
    10. this.name = name;
    11. }
    12. @Override
    13. public String toString() {
    14. return "Person0{" +
    15. "age=" + age +
    16. ", name='" + name + '\'' +
    17. '}';
    18. }
    19. @Override
    20. public int compareTo(Person0 o) {
    21. return this.age - o.age;
    22. }
    23. }
    24. public class Test13 {
    25. public static void main(String[] args) throws CloneNotSupportedException {
    26. Person0[] stu = {new Person0(21,"www"), new Person0(18,"qqq"),new Person0(25,"eee")};
    27. Arrays.sort(stu);
    28. System.out.println(Arrays.toString(stu));
    29. }
    30. }

    🪖实现Comparable接口,重写comeTo方法,调用Arrays类下的sort方法就可以对stu数组指定排序。由于sort方法中原码,是把传过去的对象强转成Comparable,然后调用comparTo方法。这就是接口和多态的强大。

    深浅拷贝 

    浅拷贝

    1. class Money{
    2. int m = 100;
    3. }
    4. class Person5 implements Cloneable{
    5. Money money = new Money();
    6. @Override
    7. protected Object clone() throws CloneNotSupportedException {
    8. return super.clone();
    9. }
    10. }
    11. public class Test14 {
    12. public static void main(String[] args) throws CloneNotSupportedException{
    13. Person5 stu = new Person5();
    14. Person5 stu1 = (Person5)stu.clone();
    15. stu1.money.m = 200;
    16. System.out.println(stu.money.m);
    17. System.out.println(stu1.money.m);
    18. }
    19. }

    🎄可以清楚看见stu1里money对象的m修改后,stu里面money对象的m也被修改了。这是因为stu和stu1所指向对象里money的地址是相同的,意味着指向的是同一个m

     

    深拷贝

    1. class Money implements Cloneable{
    2. int m = 100;
    3. @Override
    4. protected Object clone() throws CloneNotSupportedException {
    5. return super.clone();
    6. }
    7. }
    8. class Person5 implements Cloneable{
    9. Money money = new Money();
    10. @Override
    11. protected Object clone() throws CloneNotSupportedException {
    12. Person5 tmp = (Person5)super.clone();
    13. tmp.money = (Money)this.money.clone();
    14. return tmp;
    15. }
    16. }
    17. public class Test14 {
    18. public static void main(String[] args) throws CloneNotSupportedException{
    19. Person5 stu = new Person5();
    20. Person5 stu1 = (Person5)stu.clone();
    21. stu1.money.m = 200;
    22. System.out.println(stu.money.m);
    23. System.out.println(stu1.money.m);
    24. }
    25. }

    🧢 可以清楚看见改变stu1引用对象里money的m后,stu引用对象里money的m没有改变。这是由于拷贝时,改变了stu1引用对象里money的指向,意味着指向的m是不同的

     

     小结:

    🐵一些不懂的地方,可以尝试看看原码,会提升自己对代码逻辑的理解,坚持就会有不一样的收获。

  • 相关阅读:
    【计算机视觉 | 目标检测】arxiv 计算机视觉关于目标检测的学术速递(9 月 12 日论文合集)
    先来聊聊MySQL的binlog文件解析
    使用神经网络进行预测,图神经网络 社交网络
    Linux 基础-文件权限与属性
    CSDN机器学习常用科学公式写法汇总【更新中】
    使用LIMIT分页
    k8s配置StatefulSet解读
    期末人福音——用Python写个自动批改作业系统
    【小技巧】获取matlab中cdfplot函数的x轴,y轴的数值
    STM32定时器的One Pulse Mode,OPM应用
  • 原文地址:https://blog.csdn.net/weixin_62353436/article/details/126453351