在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、设计目的不同: 抽象类主要是用于代码复用和简化设计,尤其是在类层次结构中,还可以提供对子类的几个支撑方法。而接口主要用于定义对象的行为规范,以便多个类可以遵循同样的规范进行操作。
总的来说,抽象类是一个类的基础,用于表示某个类的通用行为,而接口则是一组规范,用于指导类的行为。
饿汉模式
通过定义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中两种不同的抽象方式。具体来说:
接口是一组完全抽象的方法,不包含任何具体实现,只有方法的签名。接口定义了一个规范,告诉实现该接口的类应该提供哪些方法。
抽象类是一个类,可以包含抽象方法和具体实现的方法,但是不能被实例化。抽象类可以包含成员变量,方法等,具有一定的实现,但是也定义了一些必须被子类实现的抽象方法。抽象类是定义一个类的行为方式的一种方式。
下面举例说明:
// 定义一个接口
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)。奔驰是一辆实现了这个接口的具体汽车。
// 定义一个抽象类
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!");
}
}
在这个例子中,动物是一个抽象类,它包含了动物共通的属性(如腿的数量)和方法(如步态),但一个具体的动物的声音是不同的,所以声音是一个抽象方法,必须由具体的子类实现。狗和猫是这个抽象类的两个具体实现。