java中方法的覆盖:
在Java语言中,子类可以对父类的方法进行重写,java运行时系统将根据调用该方法的实例的类型决定调用那个方法。对于子类的实例,如果子类重写了父类的方法,则运行时系统会调用子类的方法;如果子类继承了父类的方法而未重写,则运行时系统调用父类的方法。如果子类中重写了父类的方法,而在子类中又需要调用父类中被重写的方法,可以通过super来调用父类中被覆盖的方法。如下代码:
package dome;
public class Start {
public static void main(String[] args) {
// TODO Auto-generated method stub
DerivedClass test = new DerivedClass();
test.doSomething();
}
}
class SuperClass{
public SuperClass(){
System.out.println("调用了父类的构造方法!");
}
public void doSomething(){
System.out.println("调用了父类的成员方法!");
}
}
class DerivedClass extends SuperClass{
public DerivedClass(){
System.out.println("调用了子类的构造方法!");
}
public void doSomething(){
super.doSomething();
System.out.println("调用了子类的成员变量!");
}
}
运行结果为:
调用了父类的构造方法!
调用了子类的构造方法!
调用了父类的成员方法!
调用了子类的成员变量!
方法覆盖时必须遵守以下原则:
1) 覆盖后的方法不能比被覆盖的方法具有更多的访问权限。
2) 覆盖后的方法不能比被覆盖的方法产生更多的异常。
3) 声明为final的方法不能被覆盖。
4) 静态方法不能被覆盖。
课下验证:
运行示例如下代码得到结果为:
class Grandparent {
public Grandparent() {
System.out.println("GrandParent Created.");
}
public Grandparent(String string) {
System.out.println("GrandParent Created.String:" + string);
}
}
class Parent extends Grandparent {
public Parent() {
super("Hello.Grandparent.");
System.out.println("Parent Created");
// super("Hello.Grandparent.");
}
}
class Child extends Parent {
public Child() {
System.out.println("Child Created");
}
}
public class TestInherits {
public static void main(String args[]) {
Child c = new Child();
}
}
结果为:
GrandParent Created.String:Hello.Grandparent.
Parent Created
Child Created
如果将代码稍作改动如下:
class Grandparent {
public Grandparent() {
System.out.println("GrandParent Created.");
}
public Grandparent(String string) {
System.out.println("GrandParent Created.String:" + string);
}
}
class Parent extends Grandparent {
public Parent() {
//super("Hello.Grandparent.");
System.out.println("Parent Created");
super("Hello.Grandparent.");
}
}
class Child extends Parent {
public Child() {
System.out.println("Child Created");
}
}
public class TestInherits {
public static void main(String args[]) {
Child c = new Child();
}
}
则系统将报错如下:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Constructor call must be the first statement in a constructor
at Parent.<init>(TestInherits.java:18)
at Child.<init>(TestInherits.java:24)
at TestInherits.main(TestInherits.java:32)
结论:通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。
验证:
如果直接输出一个类的实例会怎样?
public class ExplorationJDKSource {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(new A());
}
}
class A{}
运行结果:
A@15db9742
结果分析:
在java中,用System.out.println()方法直接打印一个对象。它会首先判断一下该对象是否为null,如果为null,就直接打印出一个null的字符串。如果不为null,就自动调用该对象的toString方法。所以,如果改写了toString,就会直接调用toString方法了。如果没有,就是调用父类Object中的toString方法,也就是打印出内存地址。