本帖最后由 Mr.Wu 于 2016-5-22 12:53 编辑
前言:我们都知道多态的三个必要条件:
1、要有继承(实现implements)
2、要有重写(overWrite&overRide)
3、父类引用指向子类对像[ Object cat = new Cat(); ]
但是今天看见一个学友提出一个问题:
http://bbs.itheima.com/forum.php?mod=viewthread&tid=303097
咋一看,均符合多态的三个必要条件,为啥不能实现多态呢。第一感觉就是Static处有问题。所以我把源码敲了一遍,删除static后果真可以实现多态了。继而我又利用代码测试了一下Java中静态属性和和静态方法的继承以及多态问题。源码如下:
- class A//父类
- {
- public static String str = "静态属性";
- public String name = "非静态属性";
- public static void sing()
- {
- System.out.println("静态方法");
- }
-
- public void run()
- {
- System.out.println("非静态方法");
- }
- }
- class B extends A //子类B
- {
- public static String str = "B该改写后的静态属性";
- public String name = "B改写后的非静态属性";
- public static void sing()
- {
- System.out.println("B改写后的静态方法");
- }
- }
- public class C extends A //子类C继承A中的所有属性和方法
- {
- }
- public class Test_1//测试类
- {
- public static void main(String[] args)
- {
- C c = new C();
- System.out.println(c.name);
- System.out.println(c.str);
- c.sing();//输出的结果都是父类中的非静态属性、静态属性和静态方法,推出静态属性和静态方法可以被继承
-
- A c1 = new C();
- System.out.println(c1.name);
- System.out.println(c1.str);
- c1.sing();//结果同上,输出的结果都是父类中的非静态属性、静态属性和静态方法,推出静态属性和静态方法可以被继承
-
- B b = new B();
- System.out.println(b.name);
- System.out.println(b.str);
- b.sing();//结果都是子类的非静态属性,静态属性和静态方法,这里和非静态属性和非静态类的继承相同
-
-
- A b1 = new B();
- System.out.println(b1.str);//结果是父类的静态属性,说明静态属性不可以被重写,不能实现多态
- System.out.println(b1.name);//结果是父类的非静态属性,说明非静态属性不可以被重写,不能实现多态
- b1.sing();//结果都是父类的静态方法,说明静态方法不可以被重写,不能实现多态
- }
- }
复制代码
结论:
1.java中静态属性和和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏。静态方法和属性是属于类的,调用的时候直接通过类名.方法名完成的,不需继承机制就可以调用如果子类里面定义了静态方法和属性,那么这时候父类的静态方法或属性称之为“隐藏”,你如果想要调用父类的静态方法和属性,直接通过父类名.方法名或变量名完成,至于是否继承一说,子类是有继承静态方法和属性,但是跟实例方法和属性不太一样,存在“隐藏”的这种情况。
2.有了继承和重写就可以 实现父类的引用可以指向不同子类的对象。重写的功能是:“重写”后子类的优先级要高于父类的优先级,但是“隐藏”是没有这个优先级之分的。
3.静态属性、静态方法和非静态的属性都可以被 继承 和 隐藏 而不能够被重写,因此不能实现多态,不能实现父类的引用可以指向不同子类的对象。
4.非静态的方法可以被继承和重写,因此可以实现多态。
感想:
static 属性和方法均可以被继承,但是没有被重写,故实现不了多态。
当我们在学习中遇见了疑问,可以自己写代码测试同时结合搜索工具,即可找到答案。印象也会深刻。 |
|