对象替换原则:
父类的句柄能够指向父类的对象,也能够指向子类的对象。
例如:
public class A502
{
public static void main(String[] args)
{
Chinaman you = new Chinaman();
you.say();
Chinaman me = new Wuhanman();
me.say();
}
}
super与this:
关键字super指向父类对象;关键字this指向当前类对象本身。(它们是实例成员变量,不能用于静态方法之中)
1、在对象创建时使用super和this
1)如果父类的构造器重载了,通过super指定调用哪个父类构造器。
2)如果子类自己的构造器重载了,通过this在一个构造器里调用另一个构造器。
(super/this() 语句调用必须是构造器的第一个语句)
public class A
{
private String s = new String("null");
A()
{
System.out.print("A");
}
A(int a)
{
System.out.print("AAAAA");
}
A(String str)
{
this(2);
this.s = str;//若去掉,结果s为null
System.out.println(s);
}
public static void main(String[] args)
{
new A("Hello");
}
}
2、在变量的隐藏时使用super和this
1)子类的成员变量隐藏父类的成员变量
2)类的局部变量隐藏类的成员变量
(局部变量不能被隐藏)
例如:( 如果想访问父类被隐藏的成员变量i,用super.i表示。成员变量被局部变量所隐藏时,用this.i访问它。)
class F
{
int i = 100;
void isF(int i)
{
System.out.print("F"+i+"");
}
}
public class A extends F
{
int i = 10; //成员变量,隐藏了父类的成员变量i
void isA(int i) //形参变量,隐藏了自己的成员变量i
{
System.out.println("i is:"+i); //i=实际参数
System.out.println("i of A:"+this.i); //i=10
System.out.println("i of F:"+super.i); //i=100
}
public static void main(String[] args)
{
A a = new A();
int i = 1;
System.out.println(i+" ");
a.isA(i); //i=1
System.out.print(a.i+" "); //子类的对象调用成员变量
}
}
3、在消息传递中使用super和this(super主要用于方法改写中)
方法的继承与改写:
改写(overriding):在子类中对父类的方法进行重新定义,改写是继承性和多态性的核心机制。
1)子类不继承父类的private方法;如果子类与父类不在同一个包,则不继承父类的包访问级别的方法。
2)子类可以添加自己的新方法,但子类对象的引用赋值给父类句柄后,不能用父类句柄访问子类的新方法。
(构造方法不是类的成员,则父类的构造方法不能被子类继承)
注意改写与重载的区别。
方法改写要求:
1)返回值类型必须相同。
2)父类的方法不是final方法。
3)改写方法不要求与父类方法的访问修饰符相同,但不能改写的更加私有。若父类为private,改写方法可以用protected和pulic修饰;若父类为public,改写方法只能用public修饰。
4)改写方法不能产生比父类方法更多的异常。
(静态方法不能被改写,只能被隐藏。)
(private方法不被继承,static方法只能被隐藏,final方法禁止改写。)
例如:(可以通过类名和super访问父类被隐藏的类方法)
class F
{
static void fun()
{
System.out.println("F的类方法");
}
}
class S extends F
{
static void fun() //是隐藏
{
F.fun(); //类名访问被隐藏的类方法
System.out.println("Son 的类方法");
}
void inst() //实例方法
{
super.fun(); //只能用于实例方法中
System.out.println("Son的实例方法");
}
}
public class A
{
public static void main(String[] args)
{
F f = new S();
f.fun();
(new S()).fun();
(new S()).inst();
}
}
说明:父类的类方法只能被子类的类方法隐藏,不能用实例方法隐藏。父类的实例方法只能被子类的实例方法改写,不能用类方法去改写父类的实例方法。(类方法即static静态方法,实例方法即非static修饰的方法)