动手动脑之多态与异常处理

动手实验一:下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?

         m=d;

         d=m;

         d=(Dog)m;

         d=c;

         c=(Cat)m;

先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确:

java中基类对象不能当做子类对象使用,需要用强制转换来实现,子类对象变量=(子类名)基类对象名;错误的代码是d=m; d=c;

错误原因:类型不匹配:不能从 Mammal 转换为 Dog

动手实验二:运行以下测试代码

 

 

上边的程序运行结果是什么?.你如何解释会得到这样的输出?计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?请务必动脑总结,然后修改或编写一些代码进行测试,验证自己的想法,最后再看后面的PPT给出的结论。

如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。

如果子类被当作父类使用,则通过子类访问的字段是父类的!

第一个value调用的是父类的方法,输出值为100

第二个value调用的是子类的方法,输出值为200

第三个中子类赋值给父类,因此调用了子类的方法,输出值为200

第四个中调用了子类的构造方法,但是value值为100,所以没有影响

第五个中调用的是子类的方法,value的值也是子类的

改写一:

public class ParentChildTest {

public static void main(String[] args) {

Parent parent=new Parent();

parent.printValue();

Child child=new Child();

child.printValue();

parent=child;

parent.printValue();

parent.myValue++;

System.out.println(parent.myValue);

System.out.println(child.myValue);

parent.printValue();

/*((Child)parent).myValue++;

System.out.println(parent.myValue);

System.out.println(child.myValue);

parent.printValue();*/

}

}

class Parent{

public int myValue=100;

public void printValue() {

System.out.println("Parent.printValue(),myValue="+myValue);

}

}

class Child extends Parent{

public int myValue=200;

public void printValue() {

System.out.println("Child.printValue(),myValue="+myValue);

}

}

运行截图:

 

改写二:

public class ParentChildTest {

public static void main(String[] args) {

Parent parent=new Parent();

parent.printValue();

Child child=new Child();

child.printValue();

parent=child;

parent.printValue();

/*parent.myValue++;

System.out.println(parent.myValue);

System.out.println(child.myValue);

parent.printValue();*/

((Child)parent).myValue++;

System.out.println(parent.myValue);

System.out.println(child.myValue);

parent.printValue();

}

}

class Parent{

public int myValue=100;

public void printValue() {

System.out.println("Parent.printValue(),myValue="+myValue);

}

}

class Child extends Parent{

public int myValue=200;

public void printValue() {

System.out.println("Child.printValue(),myValue="+myValue);

}

}

运行截图2

 

动手实验三:请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识。

 

动手动脑四:当有多个嵌套的try…catch…finally时,要特别注意finally的执行时机。

请先阅读 EmbedFinally.java示例,再运行它,观察其输出并进行总结。

特别注意:

当有多层嵌套的finally时,异常在不同的层次抛出,在不同的位置抛出,可能会导致不同的finally语句块执行顺序。

1)、只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才可能会执行。

2)、在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行时。

3)、当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。

4)、更极端的情况,就是在线程运行 try 语句块或者 catch 语句块时,突然死机或者断电,finally 语句块肯定不会执行了。

5)、不管 try 语句块正常结束还是异常结束,finally 语句块是保证要执行的。如果 try 语句块正常结束,那么在 try 语句块中的语句都执行完之后,再执行 finally 语句块。如果 try 中有控制转移语句(returnbreakcontinuefinally 语句块在 try catch语句块中的 return 语句之前执行。

动手动脑五:辨析:finally语句块一定会执行吗?

请通过 SystemExitAndFinally.java示例程序回答上述问题

在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行时

要验证的程序

CatchWho.java

 

CatchWho2.java

 

EmbededFinally.java

 

SystemExitAndFinally.java

 

PrintExpressionStack.java

 

ThrowMultiExceptionsDemo.java

当一个方法声明抛出多个异常是,在此方法体中只要catch其中一个异常,程序就能顺利运行。

 

OverrideThrows.java

一个子类的throws子句抛出的异常,不能是其基类同名方法抛出的异常对象的父类

 

ExceptionLinkInRealWorld.java

原文地址:https://www.cnblogs.com/yanyuqing/p/4966392.html