practice9

question9_三个修饰符

1、有如下代码,请写出程序输出结果。

class MyClass {
    //静态属性a,全类共享
	static int a;
	int b;
}

public class TestMain {
	public static void main(String args[]) {
		MyClass mc1 = new MyClass();
		MyClass mc2 = new MyClass();
		mc1.a = 100;
		mc1.b = 200;
		mc2.a = 300;
		mc2.b = 400;
		System.out.println(mc1.a);
		System.out.println(mc1.b);
		System.out.println(mc2.a);
		System.out.println(mc2.b);
	}
}

300

200

300

400

2、有如下代码,请问哪些行会编译出错?

class MyClass {
	int a;
	static int b;

	void fa() {
	}

	static void fb() {
	}

	public void m1() {
		System.out.println(a); // 1
		System.out.println(b); // 2
		fa(); // 3
		fb(); // 4
	}

	public static void m2() {
		System.out.println(a); // 5
		System.out.println(b); // 6
		fa(); // 7
		fb(); // 8
	}
}

A. //1
B. //2
C. //3
D. //4
E. //5
F. //6
G. //7
H. //8

E、G 静态访问非静态报错,静态先加载

3、有如下代码,请写出该程序运行时输出的结果。

//这种方式可以用来统计创建了多少对象
class MyClass {
	static int count = 0;

	public MyClass() {
		count++;
		System.out.println(count);
	}
}

public class TestMain {
	public static void main(String args[]) {
		MyClass mc1 = new MyClass();
		MyClass mc2 = new MyClass();
		MyClass mc3 = new MyClass();
	}
}

1

2

3

4、有如下代码,请写出该程序运行时输出的结果。

class MyClass {
	static int i = 10;
	static {
		i = 20;
		System.out.println("In Static");
	}

	public MyClass() {
		System.out.println("MyClass()");
	}

	public MyClass(int i) {
		System.out.println("MyClass(int)");
		this.i = i;
	}
}

public class TestMain {
	public static void main(String args[]) {
		MyClass mc1 = new MyClass();
		System.out.println(mc1.i);
		MyClass mc2 = new MyClass(10);
		System.out.println(mc2.i);
	}
}

In Static

MyClass()

20

MyClass(int)

10

》》为什么先输出In Static而不是i

5、有以下代码,写出这个程序的运行结果。

class Super {
	public static void m1() {
		System.out.println("m1 in Super");
	}

	public void m2() {
		System.out.println("m2 in Super");
	}
}

class Sub extends Super {
    //静态方法没有多态
	public static void m1() {
		System.out.println("m1 in Sub");
	}

	public void m2() {
		System.out.println("m2 in Sub");
	}
}

public class TestMain {
	public static void main(String args[]) {
		Super sup = new Sub();
		sup.m1();
		sup.m2();
		Sub sub = (Sub) sup;
		sub.m1();
		sub.m2();
	}
}

m1 in Super

m2 in Sub

m1 in Sub

m2 in Sub

可参考这里

6、以下哪些论述是正确的

A. 静态方法中不能调用非静态方法
B. 非静态方法中不能调用静态方法
C. 静态方法不能被覆盖
D. 静态方法能够用类名直接调用
E. 可以在不产生任何一个对象的情况下调用静态方法
F. 静态方法里可以使用this

ACDE
B选项错误,非静态方法中可以调用静态方法。
F选项错误,this代表当前实例,为对象。静态方法中不能访问直接对象。

7、有如下代码,选择正确答案:

class MyClass {
	final int value;
	public MyClass() {
        
	}

	public MyClass(int value) {
		this.value = value;
	}
}

public class TestMain {
	public static void main(String args[]) {
		MyClass mc = new MyClass(10);
		System.out.println(mc.value);
	}
}

A. 编译通过,输出10
B. 编译不通过,把第2行改为final int value = 10;
C. 编译不通过,把第3行改为public MyClass(){ value = 10; }

C
这个程序选择了在构造方法时对final属性赋值。在原代码中,如果创建对象时调用了无参构造方法,在整个创建对象的过程中都没有为final属性赋值,这样会造成编译错误。

为了保证创建对象时,无论调用哪一个构造方法,final属性都会被正确赋值,要求必须在每个重载的构造函数中,都加上对final属性赋值的语句。

8、有如下代码,选择正确答案

class MyClass {
	public void printValue(final int value) {
		System.out.println(value);
	}

	public void changeValue(int value) {
		value = value * 2;
		System.out.println(value);
	}
}

public class TestMain {
	public static void main(String args[]) {
		MyClass mc = new MyClass();
		int value = 5;
		final int fvalue = 10;
		mc.printValue(value); // 1
		mc.printValue(fvalue); // 2
		mc.changeValue(value); // 3
		mc.changeValue(fvalue);// 4
	}
}

A. 编译通过
B. //1 出错
C. //2 出错
D. //3 出错
E. //4 出错

A

输出 5 10 10 20

//1, //2 均正确,因为在printValue方法中,没有修改final的形参。
//3, //4 均正确,因为在changeValue中,修改的是形参的值,而没有涉及到实参。因此不论实参 是否是final的,都不影响形参能否被修改。

9、有如下代码,下面说法正确的是:

class MyValue {
	int value;
}

public class TestFinal {
	public static void main(String args[]) {
		final MyValue mv = new MyValue();
		mv.value = 100;
		//1
		System.out.println(mv.value);
	}
}

A. 编译不通过 。
B. 编译通过。在//1 处加上:mv.value = 200; 则编译不通过
C. 编译通过。如果在//1 处加上:mv = new MyValue(); 则编译不通过。

C

final修饰引用类型,表示的是引用指向的对象不能改变。mv引用保存的地址不能改变,所指向的对象属性可以修改

10、有如下代码,以上程序是否能编译通过?如果可以,输出运行结果;如果不可以,应该怎样修改?

class Super {
	public final void m1() {
		System.out.println("m1() in Super");
	}

	public void m1(int i) {
		System.out.println("m1(int) in Super");
	}
}

class Sub extends Super {
	public void m1(int i) {
		System.out.println("m1(int) in Sub");
	}

	public void m1(double d) {
		System.out.println("m1(double) in Sub");
	}
}

public class TestMain {
	public static void main(String args[]) {
		Sub s = new Sub();
		s.m1();
		s.m1(10);
		s.m1(1.5);
	}
}

编译通过

m1() in Super
m1(int) in Sub
m1(double) in Sub

父类有m1方法,并且是final的,子类也有m1方法,但是方类的m1方法和父类的m1方法不构成方法覆盖。

11、有以下代码,这段代码哪些地方有错误?

abstract class MyAbstractClass {
	public abstract void m1(); // 1

	abstract protected void m2(){} // 2
}

class MySubClass extends MyAbstractClass {
	void m1() {
	} // 3

	protected void m2() {
	} // 4
}

A. //1
B. //2
C. //3
D. //4

BC
B选项:抽象方法不能有方法体。
C选项:子类的覆盖方法访问权限修饰符相同或更宽。默认default

12、关于abstract,以下选项正确的是:

A. abstract 类中可以没有abstract 方法
B. abstract 类的子类也可以是abstract 类
C. abstract 类不能创建对象,但可以声明引用
D. abstract 方法不能有方法体

ABCD

13、下列方法声明中正确的是:

A. abstract final void m()
B. public void final m()
C. static abstract void m()
D. private final void m()
E. private abstract void m()
F. public static final void m()

D、F

A选项abstract不能和final一起使用,abstract方法需要被重写覆盖,而final不能被覆盖

B选项顺序错误,应为public final void m()

C选项abstract被子类重写,会多态的进行调用,static没有多态

E选项private方法不能被继承,只在本类中可见abstract重写需要继承,矛盾

14、把Question8中的Shape类改为抽象类,并把其中的求周长和求面积的方法改为抽象方法。

public abstract class Shape {
	public abstract double girth();
	public abstract double area();
}

15、设计一个类MyClass,为MyClass增加一个count属性,用来统计总共创建了多少个对象。

public class MyClass {
	//创建对象数
	static int count = 0;
	public static void main(String[] args) {
		MyClass c1 = new MyClass();
		MyClass c2 = new MyClass();
		System.out.println(count);
	}
	
	public MyClass() {
		count++;
	}
	
}
上一篇:08 stack、queue和priority_queue的使用和模拟实现


下一篇:c++拷贝赋值