目录
1、接口和抽象类的区别?
1、抽象类是什么:
- 抽象类和抽象方法都使用abstract关键字进行声明
- 如果一个类中包含抽象方法,那么这个类必须声明为抽象类
- 抽象类和普通类最大的区别是,抽象类不能被实例化,只能被继承
1. 1、示例代码
-
public abstract class AbstractClassExample{ protected int x; private int y ; public abstract void func1(); public voidd fun2(){ System.out.println("func2"); } }
//抽象类只能被继承,并且要重写里面的抽象方法 public class AbstractExtendClassExample extends AbstractClassExample{ @Override public void func1(){ System.out.println("func1"); } }
// AbstractClassExample ac1 = new AbstractClassExample(); // 'AbstractClassExample' is abstract; cannot be instantiated //实例化时,抛出异常,这是个抽象类不能被实例化 AbstractClassExample ac2 = new AbstractExtendClassExample(); ac2.func1();
2、接口是什么:
1、Java8前,接口是抽象类的延伸,是一个完全抽象的类,不能有任何的方法实现
2、Java8开始,接口也可以有默认的方法实现,降低维护成本,如果添加一个新的接口,那么其他实现了该接口的类都要重写这个方法
3、Java9开始,允许将方法定义为private,这样就能定义某些复用的代码又不会暴露出去
4、接口的成员默认都是public的,不允许定义为private和 protected
5、接口的字段默认都是 static 和 final 的,必须初始化变量
6、关键字implements实现接口
2.1、示例代码
public interface InterfaceExample{
//默认是publlic的
void func1();
//java8开始有默认的方法实现,必须用default修饰
default void func2(){
System.out.println("func2");
}
//默认都是static final的,必须初始化变量值
int x = 123;
// int y; // 变量y ,没有被初始化
public int z = 0; // public可以省略
// private int k = 0; // 字段和方法都是public的,不能定义为private和proteted
// protected int l = 0; // 字段和方法都是public的,不能定义为private和proteted
// private void fun3(); //Java9开始才允许将方法定义为private
}
//接口里面的方法都是抽象方法
public class InterfaceImplementExample implements InterfaceExample {
@Override
public void func1() {
System.out.println("func1");
}
}
//接口是抽象类的延伸,一种完全的抽象类,也不能实例化
InterfaceExample ie2 = new InterfaceImplementExample();
ie2.func1();
System.out.println(InterfaceExample.x);
3、接口和抽象类的区别
1、一个类可以实现多个接口(多实现),只能继承一个抽象类(单继承)
2、接口的字段只能是static和final类型的,抽象类没有限制
3、接口的成员只能是public的,抽象类的成员没有限制
4、使用选择
使用接口:
- 需要让不相关的类都实现一个方法,例如不相关的类都可以实现 Comparable 接口中的 compareTo() 方法;
- 需要使用多实现。
使用抽象类:
- 需要在几个相关的类中共享代码。
- 需要能控制继承来的成员的访问权限,而不是都为 public。
- 需要继承非静态和非常量字段。
在很多情况下,接口优先于抽象类。因为接口没有抽象类严格的类层次结构要求,可以灵活地为一个类添加行为。并且从 Java 8 开始,接口也可以有默认的方法实现,使得修改接口的成本也变的很低。
2、反射是如何使用的?反射为很么慢?
2.1、反射是什么?
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能成为反射机制
2.2、反射能做什么?
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生成动态代理。
2.3、反射的实现原理
每个类都会有一个Class对象,包含了与类有关得到信息。编译时,会产生一个同名的.class文件。该文件中保存着Class对象。类加载就是去加载Class对象的,类在第一次使用时动态加载到JVM中。也可以使用 Class.forName("com.mysql.jdbc.Driver")
这种方式来控制类的加载,该方法会返回一个 Class 对象。
Class 和 java.lang.reflect 一起对反射提供了支持,java.lang.reflect 类库主要包含了以下三个类:
- Field :可以使用 get() 和 set() 方法读取和修改 Field 对象关联的字段;
- Method :可以使用 invoke() 方法调用与 Method 对象关联的方法;
- Constructor :可以用 Constructor 的 newInstance() 创建新的对象。
2.4、反射慢的原因
尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。
-
性能开销 :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
-
安全限制 :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。
-
内部暴露 :由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
3、什么是面向对象?面向对象和面向过程的区别?
3.1、面向对象
基于对象的概念建立模型,把所有事物当做独立的对象直接考虑问题中各个对象之间的关系
3.2、面向对象和面向过程的区别
- 出发点不同
- 层次逻辑关系不同
- 数据处理方式与控制程序方式不同
- 分析设计与编码转换方式不同
4、HashMap的数据结构?put的过程?
1. 存储结构
JDK1.7数组+链表,内部包含了一个Entry类型的数组table.Entry存储着键值对。包含了是个字段key、value、next、hash.从next字段我们可以看出Entry是一个链表。数组中的每个位置被当成一个桶,一个桶存放一个链表。
从 JDK 1.8 数组+链表+红黑树,一个桶存储的链表长度大于等于 8 时会将链表转换为红黑树。HashMap 使用拉链法来解决冲突,同一个链表中存放哈希值和散列桶取模运算结果相同的 Entry。头插法,如果查找需要分成两步进行。
1、计算键值对所在的桶
2、在链表上顺序查找,时间复杂度显然和链表的长度成正比