java中的抽象类和接口

来源:互联网 发布:酒店点菜软件 编辑:程序博客网 时间:2024/06/03 18:06

再面向对象的领域一切都是对象,同时所有的对象都是通过类来描述,但是并不是所有的类都是描述对象,如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类去支撑它,那么像这些类就是抽象类,抽象没有具体的概念。

首先说一下什么是抽象类和接口:

抽象类:抽象类是一个特殊的类,最基本就是定义抽象方法,具体由子类去继承实现。抽象类可以定义普通的成员变量,也可以有具体的实现方法,抽象类可以实现接口。抽象类表示的是,这个对象是什么。

接口:为什么有接口呢,其实接口是抽象的延伸,java为了保证的数据安全是不能多重继承的,接口的出现弥补抽象类不能多重继承的缺陷,首先接口不是类,接口是一种比抽象类更加抽象的“类”,从不能实例化一个接口就可以看出,只能创建它的实现类。接口是建立类与类之间的协议,它提供的是一种形式,没有具体的实现,当一个类实现一个接口后,就必须实现接口中的所有方法。

接口注意的问题:

1.接口的所有方法访问权限自动被声明为public,准确的说只能为public,当然可以显示声明为protected,private,但是编译会出错。

2.可以定义“成员变量”可以通过类命名直接访问。

3.不存在实现的方法。

4.实现接口的非抽象类必须要实现该接口的所有方法,抽象类可以不用实现。因为可以有它的子类去实现。

5.不能使用new去实例化,但可以声明一个接口变量,该变量必须引用一个实现接口的类的对象,可以使用instanceof检查一个对象是否实现了某个特定的接口。例如:if(object instanceod Comparable)

6.实现多接口的时候一定要避免方法名的重复。


接口与抽象类的具体区别:

1.语法层次

抽象类可以拥有任意范围的成员数据,同时也可以拥有自己的非抽象方法,但是在接口方式中,它仅能够拥有静态,不能修改的成员数据,它的所有方法都是抽象的。

子类只能继承一个抽象类,但是可以实现多个接口。

接口不能含有静态代码块以及静态方法,抽象类可以有静态代码块和静态方法。参数抽象类接口默认的方法实现可以有默认的方法实现完全抽象,不存在方法的实现实现用extends来实现,如果子类不是抽象类,需要提供抽象类所有声明方法的实现子类使用关键implements来时序接口,需要实现接口中所有声明的方法构造器抽象类可以有构造器接口不能有构造器和正常类比较除了不能实例化抽象类以外,和普通类没有任何区别接口是完全不同的类型访问修饰符抽象方法可以有public,protected和default这些修饰符接口方法默认修饰符是public,不可以使用其他修饰符main方法抽象可以有main方法并且可以运行它接口没有main方法,因此不能允许它多继承只能继承一个类和实现多个接口接口只可以继承一个或多个其他接口速度比接口速度快稍微有点慢,因为需要时间去寻找在类中实现的方法添加新方法如果往抽象类添加新的方法,可以提供默认的实现,不需要改变现在的代码往接口添加新方法,必须改变实现该接口的类

2.设计层次

2.1抽象层次不同

抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类进行抽象,包括属性,行为,但是接口却是对类局部进行抽象。

2.2跨域不同

抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类,抽象类是从子类中发现公共部分,然后泛化成抽象类,子类继承该父类。接口不同,实现它的子类可以不存在任何关系。抽象类体现的是一种继承关系,父类之间必须存在“is-a”关系,即父类和派生类在概念本质上应该是相同的。接口则不然,接口是“is-like”,仅仅是实现接口定义的契约。

2.3设计层次不同

对于抽象类,它是自下而上来设计的,要知道子类才能抽象父类,而接口则不同,根本不需要知道子类的存在,只需要定义一个规则,至于什么子类去实现它一概不知,而接口是自顶而下设计出来的。


抽象类和接口都不能创建实例化

那可能会有疑问,为什么匿名内部类中可以用new实例化

如btn,addActionListener(new ActionListener(){

   public void actionPerformed(ActionEvent e){


}


});


其实new ActionListener()是创建一个继承自ActionListener的匿名类对象,通过new表达式返回的引用自动向上转型为对ActionListener的引用


java的接口为什么不能实例化呢,首先要明白实例化的含义,实例化实际意义是在jvm的堆开辟出一块内存空间,如People people = new People();此处生命People对象people,并且实例化一个People对象,实则是在堆开辟出一块空间来存放People对象,people则是指向这块空间,也就是内存中的一块地址,这块地址所存放的值就是我们这个People对象的一些属性。

具体类所占用的内存空间所存放的值是类的成员变量,也就是栈是存放对象的引用,而堆存放的是类的成员变量。

那现在换做成一个接口,如果new出一个接口,那么这个接口就会占用堆中的一块地址,那么接口中的这块地址上能够放什么值呢?

一个接口里运行有什么:静态的属性和方法的声明,java的内存空间分为4类:栈,堆,代码,静态数据,由此见接口中所有东西的具体指都存放在代码和静态数据区因此这块地址并没有任何实际的值需要存储,所以没有必要给它一块地址来浪费空间。因此接口的实例化没有任何意义。