抽象类和接口相关

https://blog.csdn.net/yz_cfm/article/details/85779875

抽象类和接口区别

    先笼统的说一下抽象类和接口的区别以及我们在实际使用中怎么去选择使用接口还是抽象类?
    首先我们要明白,抽象类是对类的抽象,而接口是对行为的抽象。了解了这个概念后一切都好办。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口只是对类的局部(行为)进行抽象。举个例子,猫和狗都是动物,此时我们可以把猫和狗共有的属性和行为抽取出来定义一个抽象的类---Animal 类,然后 Dog 和 Cat 类就可以继承 Animal 类,然后实现自己各自的行为和属性,它们与 Animal 存在 "is-a" 的关系;但是接口仅仅是对行为的抽象,比如鸟和飞机都会飞,但是他们飞的行为不一样,我们就可以定义一个 fly 的接口,然后鸟和飞机都可以实现此接口来完成飞的动作,但是本身鸟和飞机之间并没有什么必然的联系,接口只是定义一个实现该行为的规范而已。

具体区别:
1.  抽象类通过 abstract 关键字来定义,然后子类通过 extends 继承该抽象类后并实现相应抽象方法;接口通过 interface 关键字来定义,子类通过 implements 来实现该接口中的所有方法。
2. 抽象类中的抽象方法可以使用 public、protected、default 修饰符;接口中的抽象方法默认并只能是 public,并且成员变量默认为 public static final 修饰的,所以我们可以直接通过 接口名.成员变量  使用它。
3. 抽象类中允许有非抽象的方法和成员变量包括构造方法; 接口中的方法全是抽象的,不能有方法的实现。
4. 子类只能通过继承来实现抽象类,由于 java 中的单继承特性,就导致只能继承一个抽象类;但是子类可以实现一个或多个接口,在一定程度上,这就解决了由于单继承特性所带来的问题。
5. 从作用上来看,抽象类是为了把相同的东西提取出来,即重用;接口是为了把程序进行模块化,可以降低程序的耦合。



抽象类是否可以没有方法和属性?

答案是肯定的,可以。

抽象类中可以没有抽象方法,但有抽象方法的一定是抽象类。所以,java中 抽象类里面可以没有抽象方法。注意即使是没有抽象方法和属性的抽象类,也不能被实例化。



抽象类与接口的应用场景

抽象类的应用场景:
a. 在某些情况下,某个父类只是知道其子类应该包含怎样的方法,但无法准确知道这些子类如何实现这些方法。
b. 从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为子类的模板,从而避免了子类设计的随意性。


接口的应用场景:
a. 一般情况下,实现类和它的抽象类之前具有 “is-a” 的关系,但是如果我们想达到同样的目的,但是又不存在这种关系时,使用接口。
b. 由于 java 中单继承的特性,导致一个类只能继承一个类,但是可以实现一个或多个接口,此时可以使用接口。
 

在使用中抽象类和接口我们该如何选择?
* 如果你拥有一些方法并且想让它们中的一些有默认实现,那么使用抽象类吧。

* 如果你想实现多重继承,那么你必须使用接口。由于Java不支持多继承,子类不能够继承多个类,但可以实现多个接口。因此你就可以使用接口来解决它。

* 如果基本功能在不断改变,那么就需要使用抽象类。如果不断改变基本功能并且使用接口,那么就需要改变所有实现了该接口的类。



接口的变量为啥要是public static final?

https://blog.csdn.net/ameyume/article/details/6189749

jdk1.8中,
接口中的变量默认是public static final
接口中的方法默认是 public abstract,除非是static方法或者默认方法

接口中的变量默认是public static final?
public:接口可以被不同包的不同类实现,是公有的,
static:一个类继承多个接口时,即使存在同名变量也不会混淆。如果每个接口都含有一个名为a的成员变量,那么在该类中可以通过接口1.a,接口2.a,接口3.a来调用a,
final:该变量不可被修改。如果一个接口被多个类实现时,在类1中修改了该变量的值,那么其他类中该变量的值也会变化,要防止该情况的发生。

interface X {
    public static final String name = "123";
}
 
interface Y {
    public static final String name = "456";
}
 
public class Main implements X, Y {
 
    public static void main(String[] args) {
        System.out.println(X.name);
        System.out.println(Y.name);
    }
}
//123
//456

首先你要弄清接口的含义.接口就是提供一种统一的’协议’,而接口中的属性也属于’协议’中的成员.它们是公共的,静态的,最终的常量.相当于全局常量.
抽象类是不’完全’的类,相当于是接口和具体类的一个中间层.即满足接口的抽象,也满足具体的实现.
如果接口可以定义变量,但是接口中的方法又都是抽象的,在接口中无法通过行为来修改属性。有的人会说了,没有关系,可以通过实现接口的对象的行为来修改接口中的属性。这当然没有问题,但是考虑这样的情况。如果接口A中有一个public访问权限的静态变量a。按照java的语义,我们可以不通过实现接口的对象来访问变量a,通过A.a = xxx;就可以改变接口中的变量a的值了。正如抽象类中是可以这样做的,那么实现接口A的所有对象也都会自动拥有这一改变后的a的值了,也就是说一个地方改变了a,所有这些对象中a的值也都跟着变了。这和抽象类有什么区别呢,怎么体现接口更高的抽象级别呢,怎么体现接口提供的统一的协议呢,那还要接口这种抽象来做什么呢?所以接口中不能出现变量,如果有变量,就和接口提供的统一的抽象这种思想是抵触的。所以接口中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性。

通俗的讲,你认为是要变化的东西,就放在你自己的实现中,不能放在接口中去,接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现implements)开放,接口是对开闭原则的一种体现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值