JAVA第二阶段考试试卷
第二次测验 | java |
/**
一.简答题
1.描述目前你使用过的java核心类库中的类及其对应的包。最少5个
答:java.lang.String
java.lang.System
java.lang.Math
java.lang.Object
java.util.Arrays
全限定名
String ----> java.lang
2.描述 继承中 “编译看左边,运行看右边”的含义。
答:当父类的引用指向了子类的对象时,在编译时,它的成员变量和方法是由父类确定。在运行时,结果由子类对象确定
A a = new B();
class Father(){
public void test2(){}
}
class Son(){
public void test(){}
public void test2(){
}
}
Father f = new Son();
f.test()// 当Father类中没有test()方法时,编译报错
f.test2()//当Father类中有test2()方法时,编译通过,运行结果由Son类决定。当Son类重写了父类的test2()方法,则执行Son类中的test2()方法
3.分别描述重写和重载的概念。每个概念最少从3个方面描述。
答:略 类 方法名 参数 返回类型 修饰符 static private 异常
类中有多个方法,有着相同的方法名,但是方法的参数各不相同,这种情况被称为方法的重载。
方法重载必须满足一下条件:
1)方法名相同
2)参数列表不同(参数的类型、个数、顺序的不同)
public void test(Strig str){}
public void test(int a){}
public void test(Strig str,double d){}
public void test(Strig str){}
public void test(Strig str,double d){}
public void test(double d,Strig str){}
3)方法的返回值可以不同
方法重写(方法覆盖)
1)方法重写只存在于子类和父类(包括直接父类和间接父类)之间。在同一个类中方法只能被重载,不能被重写.
2)静态方法不能重写
a. 父类的静态方法不能被子类重写为非静态方法 //编译出错
b. 父类的非静态方法不能被子类重写为静态方法;//编译出错
c. 子类可以定义与父类的静态方法同名的静态方法(但是这个不是覆盖)
例如:
A类继承B类 A和B中都一个相同的静态方法test
B a = new A();
a.test();//调用到的时候B类中的静态方法test
A a = new A();
a.test();//调用到的时候A类中的静态方法test
可以看出静态方法的调用只和变量声明的类型相关
这个和非静态方法的重写之后的效果完全不同
3)私有方法不能被子类重写
子类继承父类后,是不能直接访问父类中的私有方法的,那么就更谈不上重写了。
例如:
public class Person{
private void run(){}
}
//编译通过,但这不是重写,只是俩个类中分别有自己的私有方法
public class Student extends Person{
private void run(){}
}
4)重写的语法
1.方法名必须相同
2.参数列表必须相同
3.访问控制修饰符可以被扩大,但是不能被缩小
public protected default private
4.抛出异常类型的范围可以被缩小,但是不能被扩大
ClassNotFoundException ---> Exception
5.返回类型可以相同,也可以不同,如果不同的话,子类重写后的方法返回类型必须是父类方法返回类型的子类型
例如:父类方法的返回类型是Person,子类重写后的返回类可以是Person也可以是Person的子类型
注:一般情况下,重写的方法会和父类中的方法的声明完全保持一致,只有方法的实现不同。(也就是大括号中代码不一样)
例如:
public class Person{
public void run(){}
protected Object test()throws Exception{
return null;
}
}
//编译通过,子类继承父类,重写了run和test方法.
public class Student extends Person{
public void run(){}
public String test(){
return "";
}
}
5)为什么要重写
子类继承父类,继承了父类中的方法,但是父类中的方法并不一定能满足子类中的功能需要,所以子类中需要把方法进行重写。
4.值传递和引用(值)传递的异同点。
答:略 值: 复制后的变量 变量接收的值 不同: 地址 :操作的同一个对象
值传递和引用传递
调用方法进行传参时,分为值传递和引用传递两种。
如果参数的类型是基本数据类型,那么就是值传递。
如果参数的类型是引用数据类型,那么就是引用传递。
值传递是实参把自己变量本身存的简单数值赋值给形参.
引用传递是实参把自己变量本身存的对象内存地址值赋值给形参.
所以值传递和引用传递本质上是一回事,只不过传递的东西的意义不同而已.
3)值传递的示例
public class Test{
public static void changeNum(int a){
a = 10;// changeNum 方法中局部变量 a
}
public static void main(String[] args){
int a = 1;
System.out.println("before: a = "+a);
changeNum(a);
System.out.println("after: a = "+a);
}
}
4)引用传递的示例
public class Test{
public static void changeName(Student s){
s.name = "tom";// s 和main()中的局部变量s
//指向同一个对象
}
public static void main(String[] args){
Student s = new Student();
System.out.println("before: name = "+s.name);
changeName(s);
System.out.println("after: name = "+s.name);
}
}
5.描述类和对象的关系。
答:略 抽象 具体
类与对象的关系
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物.
例如:我们生活中所说的词语:动物、植物、手机、电脑等等
这些也都是抽象的概念,而不是指的某一个具体的东西。
例如: Person类、Room类、Car类等
这些类都是用来描述/定义某一类具体的事物应该具备的特点和行为
对象是抽象概念的具体实例
例如:
张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例。能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念.
例如:
Student s = new Student(1L,"tom",20);
s.study();
Car c = new Car(1,"BWM",500000);
c.run();
对象s就是Student类的一个实例,对象c就是Car类的一个具体实例,能够使用的是具体实例,而不是类。类只是给对象的创建提供了一个参考的模板而已.
但是在java中,没有类就没有对象,然而类又是根据具体的功能需求,进行实际的分析,最终抽象出来的.
6.OOP的特征有哪些?
答:略 具体的代码 举例生活例子
OOP特征概述
Java的编程语言是面向对象的,采用这种语言进行编程称为面向对象编程(Object-Oriented Programming, OOP)。
1)抽象(abstract)
忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用关注细节。
例如:要设计一个学生成绩管理系统,那么对于学生,只关心他的班级、学号、成绩等,而不用去关心他的身高、体重这些信息
2)封装(Encapsulation)
封装是面向对象的特征之一,是对象和类概念的主要特性。封装是把过程和数据包围起来,对数据的访问只能通过指定的方式。
在定义一个对象的特性的时候,有必要决定这些特性的可见性,即哪些特性对外部是可见的,哪些特性用于表示内部状态。
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
信息隐藏是用户对封装性的认识,封装则为信息隐藏提供支持。
封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。
3)继承(inheritance)
继承是一种联结类的层次模型,并且允许和支持类的重用,它提供了一种明确表述共性的方法。
新类继承了原始类后,新类就继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类)。
派生类(子类)可以从它的基类(父类)那里继承方法和实例变量,并且派生类(子类)中可以修改或增加新的方法使之更适合特殊的需要
继承性很好的解决了软件的可重用性问题。比如说,所有的Windows应用程序都有一个窗口,它们可以看作都是从一个窗口类派生出来的。但是有的应用程序用于文字处理,有的应用程序用于绘图,这是由于派生出了不同的子类,各个子类添加了不同的特性。
4)多态(polymorphism)
多态性是指允许不同类的对象对同一消息作出响应。
多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
相同类域的不同对象,调用相同方法,表现出不同的结果
例如:
public class Person{
public void say(){}
}
public class Student extends Person{
public void say(){
System.out.println("I am a student");
}
}
public class Teacher extends Person{
public void say(){
System.out.println("I am a teacher");
}
}
main:
Person s = new Student();
Person t = new Teacher();
s.say();
t.say();
7.描述实现数组复制的有哪几种方式。
答: 1.for 循环
2. System.arraycopy(Object src,int srcPos,Object dest, int destPos,int length)
3.Arrays.copyOf(byte[] original, int newLength)
4. int[] a = {1,2,3} int[] b = a; (不是复制)
二.编程题:
1.产生随机数5~8 (随机数包含 5,6,7,8 )
答:int num = (int)(Math.random()*4+5);
2.使用for循环实现插入排序算法
答:略 边界 起始值 i =? j =? 交换位置
插入排序
import java.util.Arrays;
public class Test{
public static void main(String[] args){
int[] array = {34,8,64,51,32,21};
System.out.println("插入排序数组为:"+Arrays.toString(array));
for(int i=1;i<array.length;i++) {
int temp = array[i];//插入元素的值
int index=i;//插入元素的下标值
//array[i]与 它前面的元素(a[0]-a[i-1])进行比较。
for(int j=i-1;j>=0;j--) {
//当a[i]比前一个元素小,将前一个元素向后移动。
if (temp < array[j]) {
array[j + 1] = array[j];
index--;//插入元素下标值减小
}
}
//最后将a[0]-a[i-1]之间移动后空缺的位置array[index]插入a[i]
array[index] = temp;
System.out.println("第"+(i+1)+"趟后数组为:"+Arrays.toString(array));
}
}
}
3.写出使用冒泡排序对该数组的排序情况
int[] a = {21, 5, 3, 9, 2, 11, 6}
第一趟排序: 21
第二趟排序: 11 21
第....排序: 9 11 21
错误: 4
4.编写代码表示多态的概念
答:略
5.编写代码求数组中的最大值
int[] a;
错误: 1.int max = 0;
2.for(){
for(){
}
}
3. for(){
int max = a[0];
if(){}
}
4. sort(a)
a[length-1]
5. for( i<10 ){
}
6. 补充该sayHello方法:如是8点至12点,返回"上午好", 12点至14点,返回"中午好" 其它时间返回"晚上好"。
public String sayHello(int hour) {
if(hour >= 8 && hour <12){
return "早上好";
}else if (hour >= 12 && hour <14) {
return "中午好";
}else {
return "晚上好";
}
}
三.代码分析题(查看每题是否编译报错或运行报错,如果编译报错或运行报错,说明报报错原因。正常运行,填写运行输出结果)(只填写报错,不填写原因,不计入成绩)
*/
//1.题:正常运行,输出 a 原因:父类的静态方法可以被子类继承,但是不能被子类重写
//测试类
public class Test {
public static void main(String[] args) {
A a = new B();
a.test();
}
}
//父类A
class A {
public static void test() {
System.out.println("a");
}
}
//子类B
class B extends A {
public static void test() {
System.out.println("b");
}
}
//思路:1。符合重写语法 编译通过
2. 局部变量初始化 编译通过
3. 运行结果 : 运行异常: 类型转换异常 空指针异常
4. 运行结果 : 成员变量 局部变量
static 非静态
初始化的执行顺序
//2.题:编译报错 父类的非静态方法不能被子类重写为静态方法
package com.briup.day01;
//测试类
public class Test {
public static void main(String[] args) {
A a = new B();
a.test();
}
}
//父类A
class A {
public void test() {//非静态方法
System.out.println("a");
}
}
//子类B
class B extends A {
public static void test() {//静态方法
System.out.println("b");
}
}
//3.题:正确运行 a a() 4
//考点:1.类加载过程中,(1)父类--->子类 (2)静态代码块-->非静态代码块
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B();
System.out.println(A.num);
}
}
//父类A
class A {
public static int num;
static{
num = 2;
System.out.println("a");
}
{
num = 3;
System.out.println("a()");
}
}
//子类B
class B extends A {
{
super.num = 4;
}
}
//4.题 编译报错 super在类中属于非静态的变量.(静态方法中不能使用)
//测试类Test
public class Test {
public static void main(String[] args) {
B b = new B();
System.out.println(A.num);
}
}
//父类A
class A {
public static int num;
public A(){
this.num = 1;
}
}
//子类B
class B extends A {
static{
super.num = 2;
}
}
//5.题 编译报错 this和super在类中属于非静态的变量.(静态方法中不能使用)
//测试类Test
public class Test {
public static void main(String[] args) {
A b = new B();
System.out.println(A.num);
}
}
//父类A
class A {
public static int num;
public A(){
this.num = 1;
}
}
//子类B
class B extends A {
public static int num;
static{
this.num = 2;
}
}
//6.题 1 2 静态成员变量对当前类的所有对象共享。成员变量 只对当前对象使用
// A new A() new A()
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new A();
A a2 = new A();
System.out.println(a2.num);
System.out.println(a2.count);
}
}
//类A
class A {
public static int count;
public int num;
public A(){
count++;
num++;
}
}
//7.题 1 原因:先执行代码块,再执行构造器
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new A();
System.out.println(a.num);
}
}
//类A
class A {
public int num;
public A(){
num = 1;
}
{
num = 2;
}
}
//8.题 原因: 该代码能否编译通过,主要是看声明变量x的类型和Y是否存在子父类的关系.有"子父类关系"就编译通过,没有子父类关系就是编译报错.
//输出结果是true还是false,主要是看变量x所指向的对象实际类型是不是Y类型的"子类型".
//测试类Test
//输出结果:1.自身 2. 子父类 3. 父子类
//4. 2个不同的类 编译报错
public class Test {
public static void main(String[] args) {
Object o = new A();
System.out.println(o instanceof B);//代码1 false
A a = new A();
System.out.println(a instanceof Object);//代码2 true
System.out.println(a instanceof B);//代码3 false
a = new B();
System.out.println(a instanceof B);//代码4 true
System.out.println(a instanceof Object);//代码5 true
}
}
//父类A
class A {}
//子类B
class B extends A {}
//9.题:编译报错 父类类型需要强制转换成子类类型 修改为: A a = (A) o;
//测试类Test
public class Test {
public static void main(String[] args) {
Object o = new A();
A a = o;
}
}
//类A
class A {}
//10.题:运行报错 java.lang.ClassCastException
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B();
C c = (C)a;
}
}
//父类A
class A {}
//子类B
class B extends A {}
//子类C
class C extends A {}
//11.题: a.test(); 编译报错 变量a的类型A中有没有定义test方法
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B();
a.test();
a.method();
}
}
//父类A
class A {
public void method(){
System.out.println("a");
}
}
//子类B
class B extends A {
public void test(){
System.out.println("b");
}
}
//12.题:运行报错, java.lang.NullPointerException
//测试类Test
public class Test {
public A a = null;
public B b;
public static void main(String[] args) {
Test t = new Test();
A a2 = t.a;// a2 = null;
B b2 = t.b;
System.out.println(a2.equals(b2));//==
}
}
//父类A
class A {}
//子类B
class B extends A {}
//13.题 a:1 b:1
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B(1);
}
}
//父类A
class A {
public A(int a){
System.out.println("a:"+a);
}
}
//子类B
class B extends A {
public int a;
public B(int b){
//a = b ;
//this.a = a;
super(b);
System.out.println("b:"+b);
}
}
//14.题:编译报错 默认无参构造器被覆盖 super(); 代码调用无参构造器报错
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B(1);
}
}
//父类A
class A {
public A(int a){
System.out.println("a:"+a);
}
}
//子类B
class B extends A {
public B(int b){
super();
System.out.println("b:"+b);
}
}
//15.题 编译报错 private 修饰的方法 在其他类中无法访问
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B();
a.method();
}
}
//父类A
class A {
private void method(){
System.out.println("a");
}
}
//子类B
class B extends A {
private void method(){
System.out.println("b");
}
}
//16.题:编译报错 重写中 权限不能缩小
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B();
a.method();
}
}
//父类A
class A {
public void method(){
System.out.println("a");
}
}
//子类B
class B extends A {
private void method(){
System.out.println("b");
}
}
//17.题:编译报错 super 和this 都在第一行,不能同时出现
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new B();
}
}
//父类A
class A {
public int a;
public A(){
a++;
}
}
//子类B
class B extends A {
public B(){
super();
this(5);
}
public B(int b){
super.a = b;
}
}
//18.题 :编译报错 重载中,返回值类型不同不能表示方法的重载。
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new A();
int num = a.method(3);
//a.method(2);
}
}
//类A
class A {
public int a;
public int b;
public void method(int a){
System.out.println("a"+a);
}
public int method(int b){
System.out.println("b"+b);
return 0;
}
}
//19.题 : 1 1
//测试类Test
public class Test {
public static void method(A a){
a.num++;//成员变量
}
public static void main(String[] args) {
int num = 1;
A a = new A(num);
System.out.println(num);// main() num
Test.method(a);//引用类型传递
System.out.println(a.num);
}
}
//类A
class A {
public int num;
public A(){}
public A(int num){
num++;//局部变量 num
}
}
//20.题:编译报错 静态方法中不能调用非静态属性
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new A();
a.method();
A.test();
System.out.println(a.i);
}
}
//类A
class A {
public int i;
public void method(){
i++;
}
public static int test(){
++i;
return i;
}
}// static 1.修饰的方法体,代码块中调用什么方法和属性 报错 : super this 成员变量 静态方法
//2.是否破坏重写 1. 2个方法 都是static 2。 static 被重写为非static
//21.题:无输出结果
//测试类Test
public class Test {
public static void main(String[] args) {
A a = new A();
a.method(10);
}
}
//类A
class A {
public void method(int i) {
if(i>5){
return;// 结束当前代码
}
System.out.println("i>5");// Dead code
}
}
//22.题: 1 2 原因: continue:不再执行循环体中continue语句之后的代码,直接进行下一次循环
for (int i = 1; i < 3; i++) {
for (int j = 1; j < 3; j++) {
if(j==2){
continue;// 结束本次循环,继续下次内循环 ,不执行后面的代码
}
System.out.println(i*j);//输出语句的位置
}
}// i j 结果
分析: 1 1 输出 1
1 2 continue 不输出
2 1 输出 2
2 2 continue 不输出
//23.题 1 2
A:for (int i = 1; i < 3; i++) {
B:for (int j = 1; j < 4; j++) {
if(j==2){
continue A;//跳转到外循环。结束内循环
}
System.out.println(i*j);
}
}
分析: 1 1 输出 1
1 2 continue 不输出
2 1 输出 2
2 2 continue 不输出
//24.题 1
A:for (int i = 1; i < 3; i++) {
B:for (int j = 1; j < 5; j++) {
if(j==2){
break A;
//break;
}
System.out.println(i*j);
}
}// i j
分析 : 1 1 输出 1
1 2 break 停止执行
1*2=2
2*2