简介
本文是2021/04/09整理的笔记
赘述可能有点多,还请各位朋友耐心阅读
本人的内容和答案不一定是最好最正确的,欢迎各位朋友评论区指正改进
易错练习题
练习题1
//MyClass.java
package corejava.chp6;
public class MyClass{
private int value;
public MyClass(){}
MyClass(int value){
this.value = value;
}
public int getValue(){
return value;
}
public void setValue(int value){
this.value = value;
}
}
//TestMyClass1.java
package corejava.chp6;
public class TestMyClass1{
public static void main(String args[]){
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass(10);
System.out.println(mc1.value);
System.out.println(mc2.value);
}
}
//TestMyClass2.java
package corejava.temp;
import corejava.chp6.*;
public class TestMyClass2{
public static void main(String args[]){
MyClass mc1 = new MyClass();
MyClass mc2 = new MyClass(10);
System.out.println(mc1.value);
System.out.println(mc2.value);
}
}
以上代码有哪些地方编译出错?假设不允许修改MyClass 类,那应该如何修改?
答案:
两个类的打印输出语句都改为
System.out.println(mc1.getValue());
System.out.println(mc2.getValue());
MyClass的有参构造方法要改为public权限
解析:
value是私有成员变量,只能通过get方法访问。
MyClass的有参构造方法是默认访问权限,只能由本类访问或同包下访问。
练习题2
1) //MyClass.java
2) package corejava.chp6;
3) public class MyClass{
4) int value;
5) }
6)
7) //MySubClass.java
8) package corejava.temp;
9) import corejava.chp6.MyClass;
10) public class MySubClass extends MyClass{
11) public MySubClass(int value){
12) this.value = value;
13) }
14) }
选择正确答案:
A. 编译通过
B. 编译不通过,应把第12 行改成super.value = value;
C. 编译不通过,应把第12 行改成super(value);
D. 编译不通过,可以为MySubClass 增加一个value 属性
E. 编译不通过,把 第4行改为protected int value; 把第12 行改为
super.value = value;
答案:
D E
解析:
MyClass和MySubClass处于不同的包下。
MyClass类中变量value是默认访问权限,只能由本类或本包的类访问。
D选项为MySubClass类添加一个value,可以解决报错的问题
E选项将访问权限改为protected ,可以由本类 本包的类 非本包的子类访问。
这样就可以使用super关键字进行访问。
练习题3
class ClassA{
public ClassA(){
System.out.println("ClassA()");
}
}
class ClassB{
public ClassB(){
System.out.println("ClassB()");
}
}
class ClassC extends ClassA{
public ClassC(){
System.out.println("ClassC()");
}
}
class ClassD extends ClassB{
private ClassA ca = new ClassA();
private ClassC cc;
public ClassD(){
System.out.println("ClassD()");
}
public ClassD(int i){
cc = new ClassC();
System.out.println("ClassD(int)");
}
}
public class TestConstructors{
public static void main(String args[]){
ClassD cd1 = new ClassD();
ClassD cd2 = new ClassD(10);
}
}
编译运行以上代码,请写出运行时输出的结果
答案
ClassB()
ClassA()
ClassD()
ClassB()
ClassA()
ClassA()
ClassC()
ClassD(int)
解析:
创建子类对象时,父类子类的代码执行顺序: 父类的构造方法 子类初始化变量 子类的构造方法
练习题4
class Meal{
public Meal(){
System.out.println("Meal()");
}
}
class Lunch extends Meal{
public Lunch(){
System.out.println("Lunch()");
}
}
class Vegetable {
public Vegetable(){
System.out.println("Vegetable()");
}
}
class Potato extends Vegetable{
public Potato(){
System.out.println("Potato()");
}
}
class Tomato extends Vegetable{
public Tomato(){
System.out.println("Tomato()");
}
}
class Meat{
public Meat(){
System.out.println("Meat()");
}
}
class Sandwich extends Lunch{
Potato p = new Potato();
Meat m = new Meat();
Tomato t = new Tomato();
public Sandwich(){
System.out.println("Sandwich()");
}
}
public class TestSandwich{
public static void main(String args[]){
Sandwich s = new Sandwich();
}
}
答案
Meal()
Lunch()
Vegetable()
Potato()
Meat()
Vegetable()
Tomato()
Sandwich()
解析:创建子类对象时,父类子类的代码执行顺序: 父类的构造方法 子类初始化变量 子类的构造方法
练习题5
class Super{
int method(){return 0;}
}
class Sub extends Super{
// 1
}
在//1 处,能编译通过的代码为:
A. public int method(){return 0;}
B. void method(){}
C. void method(int n){}
答案
AC
解析:
A.子类对父类的覆盖重写
B.错误!返回值类型需一致
C.对父类方法的重载
练习题6
class Super{
private void method(){}
}
class Sub extends Super{
//1
}
在//1 处,能编译通过的代码为:
A. public int method(){return 0;}
B. void method(){}
C. void method(int n){}
D. private void method(){}
答案
父类的方法method是私有方法,没有被继承
因此子类中可以出现同名方法
练习题7
class Super{
public void m(){
foo();
}
public void foo(){
System.out.println("foo() in Super");
}
}
class Sub extends Super{
public void foo(){
System.out.println("foo() in Sub");
}
}
public class TestSuperSub{
public static void main(String args[]){
Super s = new Sub();
s.m();
}
}
选择正确答案
A. 程序编译不通过
B. 编译通过,输出foo() in Super
C. 编译通过,输出 foo() in Sub
答案
C
解析
调用方法时,看的是运行期类型,即等号右侧。
练习题8
class Animal{
private String name;
// 1
}
class Dog extends Animal{
//2
}
class Cat extends Animal{
//3
}
public class TestAnimal{
public static void main(String args[]){
Animal[] as = new Animal[]{
new Dog("Pluto"),
new Cat("Tom");
new Dog("Snoopy");
new Cat("Garfield");
};
Dog[] dogs = getAllDog(as);
for(int i = 0; i<=dogs.length; i++){
System.out.println(dogs[i].getName());
}
}
public static Dog[] getAllDog(Animal[] as){
//4
}
}
程序填空:
a) 在 //1, //2, //3 处填上适当的get/set 方法和构造方法
b) 完成//4 处的填空。getAllDog 方法从一个Animal 数组中挑选出所有的
Dog 对象,并把这些对象放在一个Dog 数组中返回。
答案
//1
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//2
public Dog(String name) {
super(name);
}
//3
public Cat(String name) {
super(name);
}
//4
int sumDog = 0;
for (int i = 0; i < as.length; i++) {
if(as[i] instanceof Dog){
sumDog++;
}
}
Dog[] dogs = new Dog[sumDog];
int index = 0;
for (int i = 0; i < as.length; i++) {
if(as[i] instanceof Dog){
dogs[index] =(Dog) as[i];
index ++;
}
}
return dogs;
}
练习题9
//MySuperClass.java
package corejava.chp6;
class MySuperClass{
protected int value;
}
//TestMain.java
package corejava.temp;
import corejava.chp6.*;
class MySubClass extends MySuperClass{
public void print(){
System.out.println(value);
}
}
public class TestMain{
public static void main(String args[]){
MySubClass msc = new MySubClass();
msc.print();
System.out.println(msc.value);
}
}
这段代码能否编译通过?如果可以,输出结果是什么?如果不能,原因是什么?
答案:
不能通过
父类与子类不在同一包下,父类需要用public关键字修饰,否则无法继承。即使将父类所在包全部导入过来,也不行。
Protected关键字的访问权限,本类 同包下 非本包的子类
TestMain类是非本包非子类,不可以直接访问value
方法重写时的规则
- 当子类对父类方法进行重写时
- 方法签名(方法名称和参数列表)需保持一致
- 子类方法的访问权限大于等于父类方法的访问权限
- 引用类型,子类方法的返回值类型小于等于父类方法的返回值类型
- 基本类型,返回值类型保持相同。