1. 解释下什么是面向对象?面向对象和面向过程的区别?
面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
面向过程的设计思路就是首先分析问题的步骤,面向对象是以功能来划分问题,而不是步骤。
(相关资料图)
面向过程 :优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
缺点:没有面向对象易维护、易复用、易扩展
面向对象: 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护
缺点:性能比面向过程低
2. 面向对象的三大特性?分别解释下?
面向对象的三大特征封装,继承,多态。封装,封装说明一个类方法和属性与其他类的关 系,继承是父类和子类的关系,多态说的是类与类的关系。
封装隐藏了类的内部实现机制,对外界而已它的内部细节是隐藏的,暴露给外界的只是它的访问方法,保护了数据,限制对属性的 不合理操作;
继承是从已有的类中派生出新的类,新的类能继承父类的属性和方法,并能扩展新的能力。Java通过extends关键字来实现继承,父类中通过private定义的变量 和方法不会被继承。
多态必备三个要素:继承,重写,父类引用指向子类对象(多态性不适用于属性)。子类共同的操作可以先由父类来声明占坑,然后 由不同的子类分别实现,增加了代码的复用性。
3. JDK、JRE、JVM 三者之间的关系?
JVM(Java虚拟机)是整个java实现跨平台的最核心的部分,能够运行以Java写作的软件程序。
JRE 是运行JAVA程序所必须的环境的集合。
JDK 针对Java开发员的产品且Java的核心,包括Java运行环境JRE、Java工具和Java基础类库。
JDK包含JRE,而JRE包含JVM;
JDK是用于java程序的开发,而JRE则是只能运行class而没有编译的功能,所编译的class文件都必须通过JVM去执行字节码文件。java的特点之一是跨平台,它不是JAVA跨平台,而是JVM跨平台,在不同的操作系统上有不同的jvm虚拟机,因jvm,java有着**“一处执行,处处执行**”的特点。
4. 重载和重写的区别?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数 不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型 没有特殊的要求。
方法重载的规则: 1.方法名一致,参数列表中参数的顺序,类型,个数不同。 2.重载与方法的返回值无关,存在于父类和子类,同类中。 3.可以抛出不同的异常,可以有不同修饰符
方法重写的规则: 1.参数列表必须完全与被重写方法的一致,返回类型必须完全与被重写方法的返回类型一 致。 2.构造方法不能被重写,声明为 final 的方法不能被重写,声明为 static 的方法不能被重写,但是能够被再次声明。 3.访问权限不能比父类中被重写的方法的访问权限更低。 4.重写的方法能够抛出任何非强制异常(UncheckedException,也叫非运行时异常),无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广 泛的强制性异常,反之则可以。
5. Java 中是否可以重写一个 private 或者 static 方法?
java中的static方法是不可以被覆盖的,因为方法覆盖是基于运行时的动态绑定的,而static方法编译时是静态绑定的,static方法类的任何事例都不相关联。
java中也不可以覆盖private权限的方法,因为private修饰变量只能在当前类内部使用,其他类继承当前类的时候,访问不到private变量,不能覆盖!
6. 构造方法有哪些特性?
1.首先说一下java语言构造方法的特点
方法名与类名相同
没有返回类型
2.然后是构造方法和成员方法的区别
A:格式区别
构造方法和类名相同,并且没有返回类型,也没有返回值
普通成员方法可以任意起名,必须有返回类型,可以没有返回值
B:作用区别
构造方法用于创建对象,并进行初始化值,对象一建立就自动调用相对应的构造函数
普通成员方法是用于完成特定功能的
C:调用区别
构造方法是在创建对象时被调用的,一个对象建立,只调用一次相应构造函数
普通成员方法是由创建好的对象调用,可以调用多次
3. 最后是构造方法的注意事项:
A. 如果一个自定义类没有构造方法,系统会默认给出一个无参构造方法。
B. 如果一个自定义类提供了构造方法,那么,系统将不再给出无参构造方法。
这个时候,你可以不使用无参构造方法。如果你想使用,那么,就必须手动给出无参构造方法。需要注意的是,一般情况下,我们的自定义类都要手动给出无参构造方法。
7. 在 Java 中定义一个不做事且没有参数的构造方法有什么作用?
(1)子类实例化对象时,必定会调用自己的构造方法,在自己的构造方法中又必定会调用父类的构造方法(默认调用父类的无参构造方法)。
(2)如果父类没有任何构造方法,那么不会报编译上的错误,因为系统会赠送父类一个无参构造方法,但如果父类有带参数的构造方法,那么系统不会赠送父类无参构造方法了,那么子类中如果没有使用super()调用父类的有参构造方法,会报编译上的错误。
(3)解决方法就是在父类上添加一个无参构造方法,那么子类在实例化对象时,直接默认调用父类的无参构造方法,不会产生编译上的问题。
因此一个不做事且没有参数的构造方法的作用就是让子类继承父类的时候能够默认调用无参构造方法顺利实例化父类对象,而不至于产生编译上的错误。在调用子类构造方法之前会先调用父类的无参构造方法,目的是帮助子类完成初始化工作。
8. Java 中创建对象的几种方式?
4种创建对象的方法:
使用 new 关键字调用对象的构造器;
使用 Java 反射的 newInstance() 方法;
使用 Object 类的 clone() 方法;
使用对象流 ObjectInputStream的readObject()方法读取序列化对象;
1、使用 new 关键字
最常见的Java 对象的构造方法,通过调用类提供的构造器创建对象。
2、使用 newInstance() 方法
Java 反射中有一个 newInstance() 方法,可以创建对象,步骤如下:获取要创建的类的 Class 对象。如果只需要调用这个类的访问权限为 public 无参构造器,直接使用 Class 类的实例方法 newInstance()。获取 Class 对象的构造器对象,通过调用 Class 类的实例方法 getDeclaredConstractors() 来获取构造器对象的数组。(获取所有构造器,无视访问权限的限制,数组顺序按照代码中的顺序决定)如果调用的构造器是 private 的,需要调用 Constractor 类的父类 AccessibleObject 类的实例方法 setAccessible(true) 来打破访问限制。使用 Constractor 类的实例方法 newInstance()。获取 Class 对象的方法有3个,此处不多赘述。获取Constractor 对象的方法有4个,此处不多赘述。
3、使用 clone() 方法
Object 类是所有类的直接或间接父类,Object 类中提供了 实例方法 native(),在给定对象的基础上,创建一个完全相同的对象。步骤如下:想要使用 clone() 方法创建对象的类,实现 Cloneable 接口。在类的内部,重写 Object 类的 clone() 方法。
备注:
没有实现 Cloneable 接口,会抛出 CloneNotSupportedException 异常。Object 类提供的 clone() 方法,访问权限是 protected,所以如果不重写 clone() 方法,是没有权限调用的。Object 类的 clone() 方法,是 native 方法。
4、使用反序列化的 readObject() 方法
这个方法一共分两步:将对象序列化,存储到一个文件中。从文件中反序列化,得到类对象。
序列化:想要序列化对象的类,实现Serializable接口。使用文件输出流FileOutputStream创建存储序列化之后对象的文件。使用对象输出流ObjectOutputStream的实例方法writeObject(obj)。判断类中是否存在,名为writeReplace(),返回类型为Object的方法,若有,写入这个方法的返回值;否则,写入obj对象。
反序列化:使用文件输入流FileInputStream找到存储序列化对象的文件。使用对象输入流ObjectInputStream的实例方法readObject()。判断类中是否存在,名为readResolve(),返回类型为Object的方法,若有读取这个对象;否则,反序列化文件中的对象流。
备注:在类中,writeReplace()和readResoleve()是两个非常特殊的方法,其特征签名需要严格限制:方法名限定,参数个数限定为0,返回类型必须是Object,不能为Object的子类,但是可以抛出不同的异常。访问修饰符没有限制,但一般推荐为private,防止误操作。其特殊的地方还在于将其设为private方法,没有其他方法调用的情况下,编译器不会发出警告。
9. 抽象类和接口有什么区别?
10. 静态变量和实例变量的区别?
(1)语法定义上的区别
静态变量用static修饰
实例变量没有static修饰
(2)运行区别,实例区别
静态变量在类中,不属于实例对象,属于类所有,只要程序加载了字节码,不用创建实例对象静态变量就会被分配空间,已经可以使用。
实例变量是某个对象的属性,只有实例化对象后,才会被分配空间,才能使用。类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个对象将其值改变,不影响其他对象;
11. short s1 = 1;s1 = s1 + 1;有什么错?那么 short s1 = 1; s1 += 1;呢?有没有错误?
先说一下Java的基本数据类型转换规则,大的数据类型转换为小的数据类型需要强制转换,反之可以自动转换。赋值表达式等号两侧的转换的规则是右侧的向左侧的看齐,即右侧表达式要转换到和左边的类型一样。
第一题:short s1 = 1; s1 = s1 + 1;
错! s1 + 1,s1是short类型,1是int型,s1会自动转换为int型的1,与1相加后,得到int型的2,要向左侧的short类型的s1看齐,即需要通过强制类型转换。正确写法:s1 = (short) (s1 + 1);
第二题:short s1 = 1; s1 += 1;
正确! 执行s1+=1;其实执行的是s1 = (short) (s1 + 1); 其中会有一个强制转换的过程。
第三题:short s1=1,s2=1;short s3=s1+s2;
错误!这里是编译器从数据安全方面考虑,如果s1和s2都是较大的short类型数,可能会导致溢出,所以会要求强制转换到int。正确的三种写法:
12. Integer 和 int 的区别?
Integer是int的包装类;int是基本数据类型;
Integer变量必须实例化后才能使用;int变量不需要;
Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;
Integer的默认值是null;int的默认值是0。
13. 装箱和拆箱的区别
Java为每种基本数据类型都提供了对应的包装器类型。
装箱:基本类型转变为包装器类型的过程。
拆箱:包装器类型转变为基本类型的过程。
装箱是通过调用包装器类的 valueOf 方法实现的拆箱是通过调用包装器类的 xxxValue 方法实现的,xxx代表对应的基本数据类型。
如int装箱的时候自动调用Integer的valueOf(int)方法;Integer拆箱的时候自动调用Integer的intValue方法。
14. == 和 equals 的区别?
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等,如 果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量。如果没有对 equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址,诸如String、 Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
15. final、finally、finalize 的区别
final:java中的关键字,修饰符。
1.如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为absrtact抽象类的和final的类。
2.如果将变量或者方法声明为final,可以保证它们在使用中不被改变.
被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
被声明final的方法只能使用,不能重载。
finally:java的一种异常处理机制。
finally是对Java 异常处理模型的最佳补充。finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。
finalize:Java中的一个方法名。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在Object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。