java 祖父类_java父类与子类的多态性

父类:

public class base {

public String s1 = "base string";

public static String s2 = "base static string";

public void show()

{

System.out.println(this.s1);

}

public void show_static()

{

System.out.println(s2);

}

}

save_snippets.png

子类:

public class child extends base {

public String s1 = "child string";

public static String s2 = "child static string";

public void show()

{

System.out.println(this.s1);

}

public void show_static()

{

System.out.println(s2);

}

}

调用

public class mytest {

public static void main(String[] args)

{

/*

base b1 = new base();

b1.show();

child c1 = new child();

c1.show(); */

base t1 = new child();

t1.show();

t1.show_static();

System.out.println(t1.s1);

System.out.println(t1.s2);

}

}

结果:

child string

child static string

base string

base static string

结论:

多态支持实例方法,对于实例的字段,实例的静态方法等都是不支持多态。

即:实例方法的引用找的是与实例对应;而静态的内容引用找的是与变量对应。

----------------------------------------------------------父类变量调用子类实例的分割线-----------------------------------------------------------------------

通常会在代码里看到用父类的变量来接收子类的实例,然后再调用相应的方法,这样做没有什么特殊的用法,其好处减低代码的耦合度,使代码易于维护。

先看一个例子,

public class base {

public String s1 = "base string";

public static String s2 = "base static string";

public void show()

{

System.out.println(this.s1);

}

public void show_static()

{

System.out.println(s2);

}

}

public class child extends base {

public String s1 = "child string";

public static String s2 = "child static string";

public void show()

{

System.out.println(this.s1);

}

public void show_static()

{

System.out.println(s2);

}

}

public class child2 extends base {

public String s1 = "child2 string";

public static String s2 = "child2 static string";

public void show()

{

System.out.println(this.s1);

}

public void show_static()

{

System.out.println(s2);

}

}

调用类:

public class mytest {

public void f1(child cc)

{

cc.show();

}

public void f2(base bb)

{

bb.show();

}

public static void main(String[] args)

{

mytest m1 = new mytest();

child c1 = new child();

m1.f1(c1);

base b1 = new child();

m1.f2(b1);

}

}

上面是有2个方法f1,f2开始干了同样的事情;之后有需求要改变,需要把child类换类child2类;那么对于f1一套的东西来说要改3个地方【申明实例2处和参数申明1处】,而对于f2一套的东西就只改一处地方【实例处】。

想想如果参数申明的地方不是一个而是多个,甚至不同类,不同包里,改的地方就多了,还容易漏。所以f1的一套流程就没有f2的一套流程好维护。

修改为child2后的情况见下:

public class mytest {

public void f1(child2 cc)

{

cc.show();

}

public void f2(base bb)

{

bb.show();

}

public static void main(String[] args)

{

mytest m1 = new mytest();

child2 c1 = new child2();

m1.f1(c1);

base b1 = new child2();

m1.f2(b1);

}

}

----------------------------------------------------------扩展说明的分割线-----------------------------------------------------------------------

其实严格来说上面的应用还不够严谨,因为虽然父类是同样的,但子类继承父类后自己可以任意扩展的;即有可能child和child2所包含的方法不是完全一致的,这样直接等价替换,f2在调用时就有可能出现找不到方法的异常。所以最好的情况是child和child2继承自同一个接口而不是同一个类,这样就可以避免调用错误的问题了,你想怎么换就怎么换,不用再考虑2个替换类之间的内容差异了,只要新的类能完成新需求即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值