public class Father
{
public String name="Father";
public String FatherOnlyPublic="FatherOnlyPublic";
private String FatherOnlyPrivate="FatherOnlyPrivate";
public static String staticDataField="FatherStaticDataField";
public void print()
{
System.out.println("This is Father");
}
public void print(String s)
{
System.out.println(s+"父类");
}
public static void show()
{
System.out.println("This is Father class");
}
public static void show(String s)
{
System.out.println(s+"父类");
}
}
public class Son extends Father
{
public String name="Son";
public static String staticDataField="SonStaticDataField";
@Override
public void print()
{
System.out.println("This is Son");
}
public void print(String s)
{
System.out.println(s+"子类");
}
public static void show()
{
System.out.println("This is Son class");
}
public static void show(String s)
{
System.out.println(s+"子类");
}
}
public class Test
{
public static void main(String[] args)
{
/*父类类型变量引用子类类型,相同数据域,父类隐藏子类*/
Father f=new Son();
System.out.println(f.name);
//可通过强制类型转换,访问子类类型数据域
System.out.println(((Son)f).name);
//只有父类有此数据域,数据域可以继承下来
System.out.println(f.FatherOnlyPublic);
//只有父类有此数据域,数据域为私有,不可继承下来
//System.out.println(f.FatherOnlyPrivate); 无法访问FatherOnlyPrivate
System.out.println(f.toString());//f还是Son类型的类的变量
/*试一下子类中重写了父类中的print函数,直接用f调用会怎么样*/
f.print();
//结果表明,子类重写父类方法就是它的字面意思,重新写了父类中的方法,但是如果只有父类有print方法
//就是动态绑定的内容了,一直向父类找,直到找到print方法,则开始调用(把子类重写的注释掉就可以
// 观察了)
/*试一下调用重载方法*/
f.print("重载方法");
//结果表明调用的是子类中的重载方法,貌似子类中如果定义了重载方法,父类中也定义了同样的,也是重
//写了父类的重载方法。子类中没有这个重载方法,才会向父类寻找重载方法调用(把子类重写的注释掉就
// 可以观察了)
/*试一下调用静态的方法和静态数据域*/
f.show();
f.show("静态重载方法");
System.out.println(f.staticDataField);
//结果表明,调用静态方法也是采用隐藏机制的
//用强制转换试试
((Son)f).show();
((Son)f).show("静态重载方法");
System.out.println(((Son)f).staticDataField);
//结果表明,用强制转换就可以,那么
//!!无论是静态方法还是静态数据域,它在继承访问中的机制和数据域一模一样,都是父类隐藏子类,
//想要调用子类的,就得强制转换成子类
System.out.println();
/*不用父类类型变量引用子类类型,普通的情况*/
Son s=new Son();
System.out.println(s.name);//这里就变成了Son
//System.out.println(f.FatherOnlyPrivate); 无法访问FatherOnlyPrivate
System.out.println(s.toString());//为Son
s.print();
s.show();
System.out.println(s.staticDataField);
System.out.println();
Father fh=new Father();
System.out.println(fh.name);
//System.out.println(f.FatherOnlyPrivate); 无法访问FatherOnlyPrivate
System.out.println(fh.toString());
fh.print();
fh.show();
System.out.println(fh.staticDataField);
}
}
/**************************************总结***************************************/
/*
○用父类类型变量引用子类类型变量,如Father f=new Son(); 实际上f还是指Son类型的类的变量,
由System.out.println(f.toString()); 这条语句的结果就可以清楚知道。
○父类与子类有相同的数据域的情况下,父类的数据域隐藏子类的数据域,直接用f访问数据域,访问的是
父类的数据域。这里的父类的数据域应该是能继承到子类的,不然都进不了子类,更没有隐藏子类数据域
这个问题了。
○子类数据域被隐藏的情况下,要访问子类的数据域,需要进行强制类型转换,如((Son)f).name
○子类与父类有相同的实例方法的话,就是重写的问题了,子类重写父类方法就是它的字面意思,重新写了
父类中的方法,但是如果只有父类有你要调用的方法,就是动态绑定的内容了,一直向父类找,直到找到该
方法,然后开始调用。
○无论是静态方法还是静态数据域,它在继承访问中的机制和实例数据域一模一样,都是父类隐藏子类,想
要调用子类的,就得强制转换成子类,当然,这是能父类中静态方法或静态数据域能继承下来才有的问题。
○子类或父类中的重载方法,没什么特殊的,实例的重载方法符合重写规则,静态的重载方法符合隐藏规则
○而且,有个值得注意的地方,比如这里父类Father中有static方法show,那么子类Son中要定义show方
法,只能是static的,不然编译报错!
○上面两种情况,一种用父类类型变量引用子类类型,另一种不用。这其中有很大的区别!不用父类类型变
量引用子类类型的话,就没有这么多乱七八糟的重写,隐藏,重载的问题了!!访问谁的就是谁的!!!!
不过普通声明的子类也是可以访问父类中继承下来的数据的。
*/
/********************************************************************************/