第一题
1.题目:

2.解析:
首先,我们来分析Hello1类的结构和给定代码的执行流程:
Hello1类中有两个成员变量,一个静态的a和一个非静态的b。静态变量a属于类本身,而非静态变量b属于类的每一个实例(对象)。
Hello1类的构造器对成员变量b进行了初始化,将其值设置为b+a。因为a是静态的,它的值在所有实例之间是共享的。
add方法分别将a和b的值加1。
接下来,我们根据提供的代码段逐步分析:
-
Hello1 h1=new Hello1();
这一步创建了一个Hello1类的实例h1。在构造器中,b的值被初始化为b+a,即3+3=6。所以h1.b的值为6。静态变量a的值在构造过程中没有被改变,仍然是3。 -
h1.add();
调用h1对象的add方法,a的值加1变为4,h1.b的值加1变为7。 -
Hello1 h2=new Hello1();
这一步创建了另一个Hello1类的实例h2。在构造器中,b的值再次被初始化为b+a,但此时a的值已经是4(因为上一步h1.add()改变了a的值),所以h2.b的值为3+4=7。静态变量a的值在构造过程中依然没有被改变,仍然是4。 -
h2.add();
调用h2对象的add方法,a的值再加1变为5,h2.b的值加1变为8。 -
System.out.println("h1.a="+h1.a+" h2.b="+h2.b);
打印h1.a和h2.b的值。因为a是静态的,所以所有实例共享它的值,这里h1.a和Hello1.a以及h2.a都是5。而h2.b的值在上一步已经被更新为8。
所以,最终的输出结果为:
h1.a=5 h2.b=8 |
注意:虽然代码中写的是h1.a,但实际上因为a是静态的,你也可以直接通过类名Hello1.a来访问它,结果是一样的。这里写h1.a只是表明是通过h1这个对象来访问静态变量a,但实际上访问的是类级别的变量。
3.收获:
静态变量不会变,非静态变量是每个类的对象
第二题:
1.题目:

2.解析:
在Java中,类的访问权限控制是通过修饰符来决定的。在您提供的代码中,类C有三个成员变量:
private int a=3;:这个变量是私有的,只能被类C自身访问。double b=4.5;:这个变量没有明确的访问修饰符,因此它的访问权限是默认的(也称为包级访问权限),意味着它只能被同一个包内的其他类访问。protected int c=5;:这个变量是受保护的,可以被类C自身、同一个包内的其他类以及子类(无论子类是否在同一个包内)访问。
类D和类C在同一个包(com)中,因此类D可以访问类C中具有包级访问权限的变量和受保护的变量。
基于上述分析:
- 类D不能访问
a,因为a是私有的。 - 类D可以访问
b,因为b具有包级访问权限。 - 类D可以访问
c,因为c是受保护的。
因此,正确答案是:
C. 不能访问a,可以访问b和c。
3.收获:
private让变量变为私有的
第三题:
1.题目:

2.解析:
执行以下代码:
A a1 = new B(); | |
a1.print(); |
首先,A a1 = new B(); 这行代码创建了一个 B 类的实例,并将其引用赋值给了 A 类型的变量 a1。由于 B 是 A 的子类,所以这是合法的。
接下来,调用 a1.print();。这里有几个关键点需要注意:
- 变量
a1的类型是A,但是实际上它引用的是一个B类的对象。 - 在 Java 中,如果子类重写(override)了父类的方法,那么当使用子类对象调用该方法时,将执行子类中的方法实现。
- 在这个例子中,
B类重写了A类中的print方法。
因此,当调用 a1.print(); 时,实际执行的是 B 类中的 print 方法,而不是 A 类中的 print 方法。
B 类中的 print 方法只打印 a 的值,并没有对其进行自增操作。B 类中的 a 是 B 类自己的成员变量,其值为 5(由于 int a = 5; 在 B 类中被定义)。
所以,输出结果为:
a=5 |
因此,正确答案是 C. a=5
3.收获:
将子类赋值给父类
A a1 = new B()
第四题:
1.题目:

2.解析:
在Java中,当一个类继承自另一个类时,子类可以通过调用super()来调用父类的构造函数。这是子类构造函数中初始化父类部分所必需的。
在类B中,构造函数需要调用父类A的构造函数来初始化从A继承的字段a和b。由于A的构造函数接受两个int类型的参数,因此需要在B的构造函数中使用super(a, b);来调用它。
接下来,子类B还需要初始化自己的字段c,这可以通过this.c = c;来完成。
因此,完整的B类构造函数应该如下所示:
class B extends A {
private double c;
public B(int a, int b, double c) {
super(a, b); // 调用父类A的构造函数
this.c = c; // 初始化子类B的字段c
}
}
选项A中的super.A(a,b);是不正确的,因为调用父类构造函数的正确语法是super(参数列表);,而不是super.类名(参数列表);。
选项B中的A(a,b);也是不正确的,因为这不是调用父类构造函数的正确语法。而且,this.b=b;在这里是多余的,因为父类构造函数已经初始化了b。
选项C也是错误的,因为它试图通过super(a);只传递一个参数给父类构造函数,而父类A的构造函数需要两个参数。此外,this.b=b;同样是多余的。
3.收获:
子类继承父类:使用super函数继承需要的属性
第五题放一放



















