上篇博客谈到了Java中类的继承,但是那些远远不能满足我们在实际操作中的需要,那么怎么才能让子类的功能更强大,并且具有父类的属性呢?
一:
父类
1 public class A { 2 3 final String name="A"; 4 5 void A1(){}; 6 }
子类
1 public class AA extends A{ 2 3 String name="AA"; 4 5 void AA1(){}; 6 7 public static void main(String[] args) { 8 9 A a = new AA(); 10 System.out.println(a.name); 11 12 AA aa = new AA(); 13 System.out.println(aa.name); 14 15 } 16 }
输出:
A
AA
父类子类均定义了name属性
同样实例化子类,
a是父类引用
aa是子类引用
定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。
怎么使用子类强大的功能呢?就是子类重写父类定义的方法,然后自己在扩展
所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;
同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;
1 public static void main(String[] args) { 2 3 A a = new AA(); 4 System.out.println(a.name); 5 a.A1(); 6 7 AA aa = new AA(); 8 System.out.println(aa.name); 9 aa.A1(); 10 aa.AA1(); 11 12 }
A1方法在A中,A的子类AA没有重写A1方法,所以,可以访问a可以访问A1。
对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。
1 public class A { 2 3 final String name="A"; 4 5 void A1(){ 6 System.out.println("A A1()"); 7 }; 8 }
1 public class AA extends A{ 2 3 String name="AA"; 4 5 void AA1(){ 6 System.out.println("AA AA1()"); 7 }; 8 9 @Override 10 void A1() { 11 // TODO Auto-generated method stub 12 //super.A1(); 13 14 System.out.println("AA A1()"); 15 } 16 17 public static void main(String[] args) { 18 19 A a = new AA(); 20 System.out.println(a.name); 21 a.A1(); 22 23 } 24 }
输出:
A
AA A1()
没有执行父类的A1,如果要执行父类的A1,则需要
super.A1();
这正是我们需要的。
给一个简单LOL例子
英雄基类:
1 package com.jc; 2 3 abstract public class Hero { 4 5 6 abstract void run(); 7 8 public void stop(){/****/}; 9 }
堕落天使:
1 package com.jc; 2 3 public class SS extends Hero{ 4 5 @Override 6 void run() { 7 8 System.out.println("ss run()"); 9 } 10 11 @Override 12 public void stop() { 13 14 System.out.println("ss stop()"); 15 } 16 17 }
审判天使:
1 package com.jc; 2 3 public class BR extends Hero{ 4 5 @Override 6 void run() { 7 8 System.out.println("br run()"); 9 } 10 11 @Override 12 public void stop() { 13 System.out.println("br stop"); 14 } 15 16 }
执行测试
1 package com.jc; 2 3 public class Test { 4 5 @org.junit.Test 6 public void test1(){ 7 8 Hero br = new BR(); 9 10 br.run(); 11 br.stop(); 12 13 Hero ss = new SS(); 14 15 ss.run(); 16 ss.stop(); 17 18 19 } 20 }
输出:
br run()
br stop
ss run()
ss stop()
注:莫甘娜和凯尔都执行了跑和停的方法,方法都是从父类继承的,但是却出现了不同的效果。
这难道不是我们正需要的吗。O(∩_∩)O~~