抽象类和接口的区别
构造器:
接口不能有构造器,抽象类可以有构造器
成员变量:
接口默认属性都是 public static final 修饰,即使没声明也是默认
抽象类属性没有要求
方法:
接口所有方法都是抽象的,每个都要实现,修饰符必须都是pubic
抽象类只要一个方法是抽象的,就是抽象类,其他方法则没有要求,可以有自己的方法体。方法修饰符没有限制
添加新方法:
接口添加新方法,子类也要响应实现新方法。抽象类只要添加新方法就行
子类:
子类可以实现多个接口 ,不能继承多个抽象类
抽象类和接口的应用场景
抽象类:理解为“具体的模板”,A类,B类,C类共有的功能,可以把他抽象出来,要做修改只要在抽象类中修改则继承的类就会有这个功能。
接口:理解为“笼统的功能”。A类,B类,C类,都有吃饭这个功能,但是A类是吃草的,B类是吃肉,C类是吃草和吃肉都行的,所有他们都实现接口“吃饭”这个功能,然后分别根据自己的情况去实现具体的内容,如果他们都是吃草的,那么我们用抽象类就行了。
举例:“门”,有‘开门’和‘关门’的功能。我们分别把他用抽象类和接口实现
抽象类:
public abstract class Door {
public abstract void open();
public abstract void close();
}
接口
public interface Door{
public abstract void open();
public abstract void close();
}
现象我们要实现一个报警alarm()的方法。那么有2种情况:
1.那么如果我们在抽象类中Door里面实现了alarm(),则所有的子类都要实现这个方法,但是有的门并不需要报警的功能。
2.如果我们在接口Door里面实现了alarm(),则可能实现类只需要alarm功能,但是不需要open和close方法。
所以可以看出Door的open()和close()区别于alarm()方法,前者是Door的固有的功能,而alarm()方法只延伸的方法,不仅门可以有,比如墙也可以有,这样我们把alarm() 设计成接口,则门和墙都可以实现,而把open()和close()设计成抽象类,因为他们是继承的功能。
public interface Alarm(){
public abstract void alarm();
}
public class door extends Door implements Alarm{
public abstract void open();
public abstract void close();
public abstract void alarm();
}
抽象类和普通类
普通类中多一个或多个抽象方法就是抽象类,这些抽象方法只有方法的声明而没有方法体,就是让子类根据自己的情况去完成相应的业务,可以把他理解为:抽象类 = 普通类+接口 。
基本数据类型分别有哪些
有8个:
整数型:byte, short, int, long
浮点型:float, double,
字符型:char
布尔型:boolean
byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
boolean:只有true和false两个取值。
char:16位,存储Unicode码,用单引号赋值。
String s = new String(“xyz”);创建了几个String Object
两个,一个字符对象,一个字符对象引用对象
STRING与STRINGBUFFER的区别
String 的final 类型的,所以长度是不可变的,每次内容更改就会创建一个新的对象,而stringbuffer的长度可变的,内容经常改变不会创建新的对象,最后转换成String只要调用toString()方法就可以了
线程安全是什么?线程不安全是什么?
线程安全:多线程访问时,该类数据被加锁了,只有等现有的线程读取完,其他线程才可以访问(例如:Vector,HashTable)
线程不安全:多线程访问时,由于该数据没有加锁,有可能出现多个线程先后更改数据的情况(例如:ArrayList,LinkedList,HashMap等)
线程和进程的区别
集合
ArrayList和LinkedList的区别
ArrayList:是动态数组的数据结构
LinkedList :是双向链表的数据结构
数据结构
动态数组:数据排列是有序的,所以添加和删除就要移动其他数据,效率比较慢。如果查询多的情况就用动态数组,因为get 下标就可以取出来值
链表:一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。所以取数据,他要一个个寻找,很慢。如果要经常添加和删除就用这个,因为LinkedList 是双向链表结构,只要修改元素前后节点的数据连接就行了,不用去改其他数据。
ArrayList,Vector
1:Vector是线程安全的,源码中有很多的synchronized可以看出,而ArrayList不是。导致Vector效率无法和ArrayList相比;
2:ArrayList和Vector都采用线性连续存储空间,当存储空间不足的时候,ArrayList默认增加为原来的50%,Vector默认增加为原来的一倍;
Map
实现类:
1.HashMap:
1). 访问快。它是根据键hashCode值存储数据的,可以直接定位到它的值。
2)取出时排序不按照插入的顺序排序
3)非线性安全的,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致.但是可以使用Collections 的synchronizedMap方法使其具备线程安全,例:
HashMap hashMap = new HashMap();
Map<Object, Object> map = Collections.synchronizedMap(hashMap);
或者直接用ConcurrentHashMap
4)HashMap最多只有一个key值为null,但可以有无数多个value值为null。
2.LinkedHashMap:
是HashMap的一个子类,使用双向链表来维护键值对的次序,可以保证取出的顺序和插入的顺序是一致的
- Hashtable:
Hashtable是遗留类,很多映射的常用功能与HashMap类似,不同的是它承自Dictionary类,并且是线程安全的。任一时间只有一个线程能写Hashtable,并发性不如ConcurrentHashMap,因为ConcurrentHashMap引入了分段锁。Hashtable不建议在新代码中使用,不需要线程安全的场合可以用HashMap替换,需要线程安全的场合可以用ConcurrentHashMap替换。
2.Treetable