1. 面向对象都有哪些特性以及你对这些特性的理解?
类具有封装性、继承性和多态性的特性。
(1)封装性:类的封装性为类的成员提供公有、缺省、保护和私有等访问权限,目的是隐藏类中的私有变量和类中方法的实现细节。
(2)继承性:允许通过继承原有类的某些特性或全部特性而产生全新的类,原有的类称为基类(或者称为父类),产生的新类称为派生类(或者称为子类)。子类不仅可以直接继承父类的共性,而且也可以创建它特有的个性。
(3)多态性:是指在基类中定义的属性和方法被派生类继承之后,可以具有不同的数据类型或表现出不同行为,多态性有两种表现形式:重载和覆盖。(也可以讲多态性分为编译时的多态性-重载在“编译时绑定”和运行时的多态性-重写在“运行时绑定”)
面向对象的优点:易复用、易维护、易扩展,降低了系统代码的耦合度。
★注意:默认情况下面向对象有3大特性,封装、继承、多态,如果面试官问让说出四4特性,那么我们就把抽象加上去。
2. 怎么样判断方法间发生的是重写和重载?
(1)发生位置不同:
重载:发生在一类中;
重写:发生在两个类中,并且具体父子类关系。
(2)编译运行时机不同:
重载:编译期就能够判定,重载各方法间遵循“方法名相同、参数列表不同”的原则。(其中,参数列表的不同体现在参数:个数的不同、顺序的不同、类型的不同上)
重写:运行期才能确定,重写方法遵循
•签名:完全相同(方法名+参数列表)
•返回值:为void和基本数据类型时,一定要相同。如果返回值是引用数据类型时可以为父子类类型
•修饰词:子类重写的方法修饰词权限要等于或者大于父类方法的修饰词权限
•异常:子类抛出的异常类型级别等于或者小于父类抛出的异常类型级别,不能够抛出父类未捕获的异常。
★注意:publicvoidstart(inta)throwsException{},面试时,心中谨记上面这一方法,对方法的各组成部分进行一一说明即可。还有需要注意“构造方法不能被重写,声明为final的方法不能被重写,声明为static的方法不能被重写,但是能够被再次声明。”
3. 访问权限修饰符public、private、protected以及不写(默认)时的区别?
不同的权限修饰符的区别通过下表说明:
修饰词 | 当前类 | 同包 | 子类 | 其他包 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
默认 | √ | √ | × | × |
private | √ | × | × | × |
4. abstractclass和interface有什么区别?
1.相同点: A. 两者都是抽象类,都不能实例化。 B. interface实现类及abstractclass的子类都必须要实现已经声明的抽象方法。2.不同点:
A. interface需要实现,要用implements,而abstractclass需要继承,要用extends。 B. 一个类可以实现多个interface,但一个类只能继承一个abstractclass。 C. interface强调特定功能的实现,而abstractclass强调所属关系。 D. 尽管interface实现类及abstractclass的子类都必须要实现相应的抽象方法,但实现的形式不同。interface中的每一个方法都是抽象方法,都只是声明的(declaration,没有方法体),实现类必须要实现。而abstractclass的子类可以有选择地实现。5. 简单讲一下java的跨平台原理
java源程序(.java文件)通过编译器编译成为Class文件(字节码文件),而它的class文件是基于字节码(以byte为单位存储的文件)的,而字节码文件是描述程序要运行的的虚指令的集合,这些虚指令的集合与任何的平台无关,Java虚拟机认识它(只要在不同的平台下部署相应的JRE,运行JVM就可以了)。
6. Java的基本数据类型都有哪些各占几个字节?
8种基本数据类型分别用于存储:整数数据、浮点数据、字符数据、布尔类型数据
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也可以不加。
char:16位,存储Unicode码,用单引号赋值。
boolean:只有true和false两个取值。
★注意:这里的‘位’是指:二进制位数,一个字节占8个二进制位。
7. 有了基本数据类型,为什么还需要包装类型?
我们知道Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型,原因是集合中能存储对象类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。从Java5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java为每个原始类型提供了包装类型:
-原始类型:boolean,char,byte,short,int,long,float,double
-包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
8. 数据类型之间的转换
(1)字符串如何转基本数据类型?
调用基本数据类型对应的包装类中的方法parseXXX(String)或valueOf(String)即可返回相应基本类型。
(2)基本数据类型如何转字符串?
一种方法是将基本数据类型与空字符串(“”)连接(+)即可获得其所对应的字符串;另一种方法是调用String类中的valueOf()方法返回相应字符串。
9. &和&&的区别?
&和&&都可以用作逻辑运算符,表示逻辑与。当运算符两边的表达式都为true时,结果才为true;否则,结果为false。另外&&还具有短路功能,也就是说,当&&左边的表达式结果为false时,将不再运算&&右边的表达式,结果肯定为false。
例如,对于if(str!=null && !str.equals(“”)),当str为null时,不会对&&右边的表达式进行运算,否则会出现空指针异常。&还可以用作位运算符,当&两边的表达式不是boolean类型时,&表示按位与。
★注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
10. 在Java中,如何跳出当前的多重嵌套循环在最外层循环前加一个标记如A,然后用break A;可以跳出多重循环。(Java中支持带标签的break和continue语句,作用有点类似于C和C++中的goto语句,但是就像要避免使用goto一样,应该避免使用带标签的break和continue,因为它不会让你的程序变得更优雅,很多时候甚至有相反的作用,这个大家需要在通过项目的多次洗礼后慢慢就会有感受了)。
public static void main(String[] args) { A: for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { System.out.println("[i=" + i + ",j=" + j + "]"); if (j == 3) { break A; } } }}
11. Java 有没有 goto 语句?
goto 是Java中的保留字,在目前版本的Java中没有使用。根据 James Gosling(Java 之父)编写的《The Java Programming Language》一书的附录中给出了一个Java关键字列表,其中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉C语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字。
流程控制语句
12. break ,continue ,return 的区别及作用?
(1) break 跳出当前层循环,不再执行循环(结束当前的循环体)
(2) continue 跳出本次循环,继续执行下次循环(结束正在执行的循环,进入下一个循环条件)
(3) return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)
13. 什么是多态机制?Java语言是如何实现多态的?
所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。
多态的实现:
Java实现多态有三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。
对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。
14. 面向对象五大基本原则是什么?
(1)SRP单一职责原则(Single Responsibility Principle)
类的功能要单一,不能包罗万象,跟杂货铺似的。 (2) OCP 开放封闭原则 (Open-Close Principle) 一个模块对于拓展是开放的,对于修改是封闭的。 (3) L SP 里式替换原则 ( the Liskov Substitution Principle LSP ) 子类可以替换父类出现在父类能够出现的任何地方。 (4) DIP 依赖倒置原则 ( the Dependency Inversion Principle DIP ) 高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。 (5) ISP 接口分离原则( the Interface Segregation Principle ISP ) 设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。15. 构造器如何工作?
Java 在构造实例时的顺序是这样的:
(1)分配对象空间,并将对象中成员初始化为 0 或null, java不允许用户操纵一个不定值的对象。
(2)执行属性值的显式初始化
(3)执行构造器
(4)将变量关联到堆中的对象上
16. super 与 this 的区别?
不同点:
(1)super()主要是对父类构造函数的调用,this()是对重载构造函数的调用;
(2)super()主要是在继承了父类的子类的构造函数中使用,是在不同类中的使用;this()主要是在同一类的不同构造函数中的使用。
相同点:
super()和 this()都必须在构造函数的第一行进行调用,否则就是错误的。
17. 构造器 Constructor 是否可被 override?
构造器Constructor不能被继承,因此不能重写Override,但可以被重Overload。每一个类必须有自己的构造函数,负责构造自己这部分的构造。子类不会覆盖父类的构造函数,相反必须子类在自己的构造方法的一开始要调用父类的构造函数。
18. 内部类可以引用他包含类的成员吗?有没有什么限制?
完全可以。如果不是静态内部类,那没有什么限制!如果把静态嵌套类当作内部类的一种特例,那在这种情况下不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员。
19. final、finally、finalize 的区别?
(1)final:用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,被其修饰的类不可继承。
(2)finally:异常处理机制中处理语句结构的一部分,表示总是执行。
(3)finalize:Object 类的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。该方法更像是一个对象生命周期的临终方法,当该方法被系统调用则代表该对象即将“死亡”,但是需要注意的是,我们主动行为上去调用该方法并不会导致该对象“死亡”(可能不会马上执行,像是做了提醒动作),这是一个被动的方法(其实就是回调方法),不需要我们调用。
20. 当一个对象被当作参数传递到一个方法后,到底是值传递还是引用传递?
是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的。C++和C#中可以通过传引用或传输出参数来改变传入的参数的值。说明:Java 中没有传引用实在是非常的不方便,这一点在Java 8中仍然没有得到改进,正是如此在Java编写的代码中才会出现大量的封装类(将需要通过方法调用修改的引用置于一个封装类中,再将封装对象传入方法),这样的做法只会让代码变得臃肿,尤其是让从C和C++转型为 Java 程序员的开发者无法容忍。
21. 成员变量与局部变量的区别有哪些?
变量: 在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存中的一小块区域。 (1)成员变量: 方法外部,类内部定义的变量 (2)局部变量:类的方法中的变量。 成员变量和局部变量的区别 • 作用域 成员变量:针对整个类有效。 局部变量:只在某个范围内有效。(一般指的就是方法,语句块内) • 存储位置 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。 • 生命周期 成员变量:随着对象的创建而存在,随着对象的消失而消失。 局部变量:当方法调用完,或者语句结束后,就自动释放。 • 初始值 成员变量:有默认初始值。 局部变量:没有默认初始值,使用前必须赋值。 • 使用原则 在使用变量时需要遵循的原则为: 就近原则 。即: 首先在局 部范围找,有就 使用; 接着在成员位置 找。22. 静态变量、实例变量和普通变量区别
静态变量: 属于类的,不属于任何实例对象,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间。
实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量。
普通变量:static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。还有一点就是static成员变量的初始化顺序按照定义的顺序进行初始化。
23. 静态方法和实例方法有何不同?
区别主要体现在两个方面:
(1)在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
(2)静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。
24. 抽象类和接口有什么区别?
抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。
从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
相同点:
(1)接口和抽象类都不能实例化
(2)都位于继承的顶端,用于被其他实现或继承
(3)都包含抽象方法,其子类都必须覆写这些抽象方法
不同点:
• 声明方式:抽象类使用abstract关键字声明;接口使用interface关键字声明。
• 实现方式:抽象类的子类使用extends关键字来继承。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现;接口的子类使用implements关键字来实现。它需要提供接口中所有声明的方法的实现。
• 访问修饰符:抽象类中的方法可以是任意访问修饰符;接口方法默认修饰符是public。并且不允许定义为 private 或者 protected。
• 多继承:一个类最多只能继承一个抽象类;一个类可以实现多个接口。
• 字段声明:抽象类的字段声明可以是任意的;接口的字段默认都是 static 和 final 的。
• 构造器:抽象类可以有构造器;接口不能有构造器。
★注意:Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。
25. switch 是否能作用在 byte 、long 、 String 上?
在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。
※ 往期内容:
教学项目-UMS系统-【1】开发思路
教学项目-UMS系统-【2】搭建maven、Tomcat环境
教学项目-UMS系统-【3】项目创建和数据库表设计