1.面向对象和面向过程的区别
面向过程:
优点:性能要高于面向对象,面向对象中的类在调用的时候需要实例化,中间需要加载的资源比较多(单片机、嵌入式开发、linux一般使用面向过程的思想进行开发)
缺点:不易维护,不易复用,不易扩展
面向对象:
优点:易于维护,易于复用,易于扩展,因为封装、继承、多态等特性的存在,所以能够设计出耦合度很低的系统,并使系统更加灵活
缺点:性能比面向对象低
2.JAVA语言的特点
1.面向对象(封装、继承、多态)
2.可靠安全
- 无指针运算(没有指针的话,就不能随便的去访问不该访问的内存)
- 数组边界检查
- 强制类型转换检查
3.支持多线程还有网络编程
3.什么是JAVA虚拟机?什么是字节码?
Java虚拟机是在机器和程序之间加入了一层虚拟的机器。这层虚拟机在任何平台上都为程序提供了一层共同的接口,所以Java程序易移植。程序只需要面向虚拟机,再由虚拟机来面向机器工作。源程序经过编译后生成虚拟机能够理解的字节码文件,字节码文件再由虚拟机来解释执行。虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的特定机器码,然后再在特定的机器上运行
使用字节码的好处:使java程序可移植性很强
4.什么是JAVA的主类
主类即包含main()方法的类,主类是java程序执行的入口点
5.JDK和JRE是什么?
JDK即JAVA开发包(java development kit)
JRE即JAVA运行环境(java runtime environment)
JDK包含了JRE JDK还包括
- javac ------编译器,将.java后缀的源文件编译成.class的字节码文件
- java------运行工具,运行.class文件
- jar------打包工具
- javadoc------文档生成器
- jdb debugger------调试工具
普通用户只需要安装JRE来运行java程序,而开发者必须安装JDK来进行开发
6.重载和重写的区别
重载:发生在同一个类中,多个方法的方法名相同,但是参数类型不同,参数数量不同,参数顺序不同,方法返回值和访问修饰符可以不同,发生在编译时
重写:发生在具有继承关系的两个类中,一般是子类和父类。
1.参数列表要相同
2.返回类型要与被重写的方法完全相同
3.抛出的异常要小于等于父类
4.访问修饰符要大于或等于父类的访问修饰符
5.如果父类的方法为private或者final,则子类不能构成重写
6.被声明为static的方法不能被重写,但是可以被再次声明
7.构造方法不能被重写
对父类方法进行重写要注意“三同、一小、一大”
- 三同:返回值类型、方法名、形参列表相同
- 一小:抛出的异常比父类声明抛出的异常要小
- 一大:子类的方法访问修饰符要跟父类方法相等或者更大
7.封装继承和多态
封装:
- 定义 隐藏对象的属性和实现细节,对外只公开调用接口
- 目的 增强安全性
- 基本要求 把所有属性私有化,对每个属性提供get和set方法,如果有一个有参构造函数的话,一定要写一个无参构造函数。有时还重写toString()方法,但是不是必须的
继承:
- 目的 实现代码的复用
- 子类不能继承父类的构造方法和私有属性
- 子类不能继承父类的访问控制符为private的方法
多态:
- 实现多态的三个条件 ---必须是继承关系--- ---子类重写了父类的方法--- ---父类的引用指向子类的对象(向上转型)---
- 多态就是一个对象的多种形态,同样的变量,调用同样的方法,却产生不同的行为例:Person是Man的父类,都有walk()方法,Person p1 = new Person(); p1.walk() 调用的是父类的方法, Person p2 = new Man(); p2.walk() 调用的是子类的方法 但是p2不能调用子类新增的方法work(),必须要向 下转型才能调用子类新增的方法 Man p = (Man)p2; p.work()
-
(1)如果子类重写了父类的某个方法,那么调用的就是子类的方法
(2)如果子类没有重写父类的方法,那么调用的就是父类的方法
(3)如果子类中增加了父类中没有的新方法,那么这个父类引用是不能调用子类中的这个新方法的,因为子类对象自动向上转型成了父类对象
(4)如果子类与父类有同名的成员变量或者静态变量,那么子类自动向上转型成父类对象,那么输出的必然是父类的变量
(5)如果PersonA AA = new PersonA(),那这就是一个实实在在的子类对象,那么A.a就会覆盖父类的同名变量,如果子类中没有同名变量,那么调用的就是父类的a,也就是说子类可以继承父类的成员变量和静态变量,同时也可以覆盖父类的成员变量和静态变量
8.接口和抽象类的区别
接口:
- 一个接口可以被多个类实现,一个类也可以实现多个接口
- 接口中的所有字段都默认是static final,所以修饰符写不写都是一样的,接口的所有方法都默认是抽象方法,默认修饰符为static abstract,写不写都是一样的
- 接口没有构造方法
不同点:
- 接口可以多实现,但是抽象类只能单继承
- 抽象类中可以有非抽象的方法和构造方法、变量,但是接口只能有抽象方法和静态常量,接口中不能有普通数据成员,必须是静态的且不可改变的数据成员,要用static final来修饰
- 抽象类和子类具有父子关系,子类能拥有父类的一些属性。接口虽然是由某一个类来实现,但是因为接口中的都是静态常量,所以不构成继承关系
相同点:
- 无论是接口还是抽象类,都不能直接实例化,而是需要依靠实现类或者子类来实例化
- 接口和抽象类都必须实现其中的所有方法
总结:
某种意义上来说接口是一种特殊的抽象类,如果你不需要刻意表达属性上的继承的话,你可以用接口来代替抽象类
9.equals()和 ==的比较
- 通俗的拿人举个例子,==其实是看左边的人和右边的人是不是同一个人,而equals()是看左边的人和右边的人是不是长得相同,但是长相相同不一定是一个人
- 用术语说的话==判断的是两个变量或者实例指向的内存地址是否相同,而equals()比较的是两个变量或者实例指向的内存地址中存储的值是不是相同
- ==比较的是内存地址,equals()比较的是值
10.String和StringBuffer还有StringBuilder的区别
- 可变性
- String类中使用的字符数组来保存字符串,private final char value[],所以String是不可变的
- StringBuffer和StringBuilder都是继承自AbstractStringBuilder类,AbstractStringBuilder也是使用字符数组来保存字符串char[]value,所以这两种对象是可变的
- 线程安全
- 因为String是不可变得,相当于常量,所以是线程安全的(安全)
- StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的(安全)
- StringBuilder没有加同步锁,所以是非线程安全的(不安全)
- 性能
- 每次对String进行改变的时候,都会生成一个新的String对象,然后将引用指向新的String对象
- 每次对StringBuffer进行改变的时候,都是相当于在原对象中对内容进行append()追加,并不生成新的对象,也不改变引用
- StringBuilder在相同情况下相对StringBuffer能提升10%-15%的性能,但是要冒线程不安全的危险(性能提升是因为没加同步锁)
- 使用情况总结
- 操作少量数据的情况下---使用String---
- 单线程下字符缓冲区下操作大量数据---使用StringBuilder---
- 多线程下字符缓冲区下操作大量数据---使用StringBuffer---
11.为什么在一个静态方法内部调用一个非静态成员是非法的?
因为静态方法可以通过---类名.静态方法名---来调用的,可以不创建对象,所以在静态方法中不能调用非静态的变量,也不能访问非静态的成员
12.定义一个无参构造函数的作用是什么?
JAVA程序在执行子类的构造方法之前,如果没有用super()来调用特定的父类构造方法,那么就会调用父类的无参构造函数,因此如果父类中没有无参构造函数,并且子类没有使用super()来调用特定的父类构造函数的话,将在编译时发生错误,原因是无法在父类中找到可执行的无参构造方法,所以要在父类中加入一个无参构造函数
13.成员变量和局部变量的区别
- 成员变量可以被public private static等修饰符所修饰,而局部变量不能被修饰,但是两者都可以被final修饰
- 从变量在内存中的存储位置来看,成员变量跟对象一样存储在堆中,但是局部变量存储在栈中,方法调用完即消失
- 成员变量如果创建时没有被手动赋值,则会以类型的默认值赋值,而局部变量不会被自动赋值
14.类的构造方法的作用是什么?不手动写构造方法的话,程序可以执行吗?
构造方法的作用是对这个类的实例进行初始化,不写的话,程序会自动加上一个默认的无参构造函数
15.对象相等和引用相等,两者有什么不同?
对象相等比较的是内存中存放的内容是否相等,而引用相等比较的是两个引用指向的内存地址是否相等