接口和抽象类之间的区别

在Java中,接口和抽象类之间的区别是什么?
接口和抽象类都是用来定义对象的公共行为的,但二者有什么不同

接口和抽象类都是用来定义对象的公共行为的,但二者有以下 7 点不同:

定义的关键字不同:接口使用关键字 interface 来定义,抽象类使用关键字 abstract class来定义;
子类继承或实现关键字不同:接口实现使用 implements 关键字,抽象类实现继承使用 extends 关键字;
类型扩展不同:抽象类是单继承,而接口是多继承;
方法权限控制符:抽象类无限制,只是不能被 private 修饰;而接口默认且只能是 public 修饰;
属性权限控制符:抽象类无限制,而接口默认且只能是 public 修饰;
方法实现不同:抽象类中可以有普通方法、抽象方法;而接口中可以有抽象方法、在 JDK 8 后还加入了 static 和 defualt 方法;
静态代码块的使用不同:抽象类可以有静态代码块,而接口不能有。

接口和抽象类的主要区别在于它们的实现方式、方法和用途:
1.抽象类是一种特殊的类,不能被实例化,只能被继承。抽象类可以包含实例变量、构造函数、普通方法和抽象方法。而接口是一种特殊的类型,它只包含抽象方法和常量字段。
2.抽象类中的抽象方法必须由其子类实现,而接口中的所有方法都必须由其实现类实现。抽象类中可以包含普通方法和实例变量,而接口中只能包含常量和抽象方法。
3.抽象类中的普通方法可以是具体实现的方法,也可以是虚方法(未实现的方法),而接口中的所有方法都必须被实现。
4.一个类可以实现多个接口,但只能继承一个抽象类。
5.接口中的方法默认是public和abstract的,而抽象类中的抽象方法可以有不同的访问修饰符。
6.接口中的常量字段默认是public static final的,而抽象类中的常量字段可以是private或者是protected。
7.接口中的方法不能使用final关键字来修饰,而抽象类中的抽象方法可以被final关键字修饰,表示该方法不能被子类重写。
8.接口中的方法默认是public abstract的,而抽象类中的抽象方法可以有不同的访问修饰符。

在Java中,接口和抽象类都可以用来定义对象的公共行为,但它们之间存在一些重要的区别。
1、实现方式不同:抽象类是一个普通的类,其中可以包含实例变量、抽象方法、非抽象方法等。而接口只能包含常量与方法的定义,其中方法只能是抽象方法或默认方法。接口中的方法都是 Public 且抽象的,该特性使得接口很适合定义纯粹的行为规范。
2、多继承支持不同: Java中一个类只能继承一个父类,但可以实现多个接口。由于接口只包含规范,而不包含实现,因此它可以随意组合成新的特质。这使得接口更加灵活,可以更好地适应复杂的类层次结构和功能需求。
3、设计目的不同: 抽象类主要是用于代码复用和简化设计,尤其是在类层次结构中,还可以提供对子类的几个支撑方法。而接口主要用于定义对象的行为规范,以便多个类可以遵循同样的规范进行操作。

总的来说,抽象类是一个类的基础,用于表示某个类的通用行为,而接口则是一组规范,用于指导类的行为。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7589302
  • 这篇博客也不错, 你可以看下Java中成员变量与局部变量的区别、对象类型作为方法的参数和方法的返回值
  • 你还可以看下java参考手册中的 java-二维图形 - 如何在应用程序中显示和打印二维图形。-Java 2D中的高级主题解释了如何执行变换、剪辑绘图区域、合成重叠的图形、指定渲染首选项以及控制渲染质量。-合成图形
  • 除此之外, 这篇博客: 某Java大佬在地表最强Java企业(阿里)面试总结中的 2.29、 如何创建单例模式?说了双重检查,他说不是线程安全的。如何高效的创建一个线程安全的单例? 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 饿汉模式
    通过定义final型的对象,来让加载类的时候,直接创建对象,只加载一次,实现单例。
    懒汉式
    通过定义静态对象,加锁去实例化对象。
    枚举
    通过定义枚举类,来实现单例。

    Double-Check
    若有两个线程通过了第一个Check循环,进入第二个Check循环是串行化的,只能有一个线程进入,这样当这个线程创建完成后,另外的线程就无法通过第二个循环了,保证了实例的唯一性,随后的线程也不会通过第一个Check循环,也就不会有同步控制的环节了。但是,这种方法也伴随着一个缺点,它可能会引起空指针的异常。
    高效创建线程安全的单例

    Volatile+Double-Check
     volatile关键字可以防止重排序的发生,在此不对volatile作详细介绍,通过volatile关键字,这种模式可以说是满足懒加载、多线程下单例的唯一性、安全性的。

    public final class SingletonObject5 {
       
        private volatile static SingletonObject5 instance ;
     
        private SingletonObject5() {
        }
     
        public static SingletonObject5 getInstance() {
            if (null == instance) {
                synchronized (SingletonObject5.class) {
                    if (null == instance)
                        instance = new SingletonObject5();
                }
            }
            return SingletonObject5.instance;
        }
    }
    
  • 您还可以看一下 汪翠老师的java项目实战之欢乐斗地主游戏开发教程 毕业项目课程设计带源码课程中的 游戏效果展示小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    接口和抽象类是Java中两种不同的抽象方式。具体来说:

    1. 接口是一组完全抽象的方法,不包含任何具体实现,只有方法的签名。接口定义了一个规范,告诉实现该接口的类应该提供哪些方法。

    2. 抽象类是一个类,可以包含抽象方法和具体实现的方法,但是不能被实例化。抽象类可以包含成员变量,方法等,具有一定的实现,但是也定义了一些必须被子类实现的抽象方法。抽象类是定义一个类的行为方式的一种方式。

    下面举例说明:

    1. 接口
    // 定义一个接口
    public interface Car {
        void start();
        void stop();
    }
    
    // 实现该接口的类
    public class Benz implements Car {
        @Override
        public void start() {
            System.out.println("Benz is starting...");
        }
    
        @Override
        public void stop() {
            System.out.println("Benz is stopping...");
        }
    }
    

    在这个例子中,车是一个接口,它定义了所有车应该有的方法,如启动(start)和停止(stop)。奔驰是一辆实现了这个接口的具体汽车。

    1. 抽象类
    // 定义一个抽象类
    public abstract class Animal {
        protected int legs;
        protected Animal(int legs) {
            this.legs = legs;
        }
        public void walk() {
            System.out.println("This animal is walking on " + legs + " legs.");
        }
        // 抽象方法,必须由子类实现
        abstract void sound();
    }
    
    // 实现该抽象类的具体类,狗类
    public class Dog extends Animal {
        public Dog() {
            super(4);
        }
        @Override
        void sound() {
            System.out.println("Woof!");
        }
    }
    
    // 实现该抽象类的具体类,猫类
    public class Cat extends Animal {
        public Cat() {
            super(4);
        }
        @Override
        void sound() {
            System.out.println("Meow!");
        }
    }
    

    在这个例子中,动物是一个抽象类,它包含了动物共通的属性(如腿的数量)和方法(如步态),但一个具体的动物的声音是不同的,所以声音是一个抽象方法,必须由具体的子类实现。狗和猫是这个抽象类的两个具体实现。