一、面试题
面试题 LVXQ.java 代码如下
public class LJXQ { public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a.get(a) + " - " + a.get(d) + " - " + a.get(b) + " - " + b.get(a) + " - " + b.get(c) + " - " + b.get(d)); } } class A { String get(D d) { return "AD"; } String get(A a) { return "AA"; } } class B extends A { String get(A a) { return "BA"; } String get(B b) { return "BB"; } } class C extends B { } class D extends B { }
请写出运行结果;答案暂不公布,可以尝试解决,看看自己的继承掌握的如何。
二、继承
2-1.继承定义
特殊类的对象拥有一般类的全部属性与行为,称为特殊类对一般类的继承。
Java的三大特性,继承、封装、多态。在C++中也有继承,不过是多继承,子类可以有多个父类,而Java中不支持多继承,子类只能有一个父类或者没有父类。所谓继承,简单理解可以从字面意思去认识学习,就是"子"可以继承"父"所拥有的属性及方法。传承接收后就是自己的属性或方法。
2-2.继承说明
这里说道继承是拥有父类的全部属性和方法,但我们发现父类的私有属性,子类是不可以使用的。这违背了继承的定义吗,拥有父类的全部属性与行为。答案是没有。用数学去描述子类与父类的话,应该是子类大于等于父类。在一个子类被创建时,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者结合形成子类的对象。所以父类的全部属性和行为子类会拥有,但是对于父类对象中的私有属性和方法,子类是无法访问到的,只是拥有,但也仅仅是拥有(I like you, But just like you!)。这也是关键字private,protected,public的意义所在。
三、面试题分析
我们使用一个不大聪明的方法去解决这个问题。我把所有的方法都写出来。就能直观的看出结果,当然重点是子类是如何继承父类的行为的。是对继承这一特性知识掌握的测试。
补充子类全部方法后的 DDDL.java
/** * Java单继承面试题 * 补充子类中包含的全部方法 * @author niaonao */ public class DDDL { public static void main(String[] args) { A a = new A(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a.get(a) + " - " + a.get(d) + " - " + a.get(b) + " - " + b.get(a) + " - " + b.get(c) + " - " + b.get(d)); } } class A { // TODO String get(D d) { return "AD"; } // TODO String get(A a) { return "AA"; } /* * 说明:类B 继承于A,get(B b)直接继承get(A a) * 关系:class A -> get(A a) */ String get(B b) { return "AA"; } /* * 说明:类C 继承于B,父类B 中没有方法get(C c),类B 的父类A 中也没有该方法,类方法就近继承get(A a) * 关系:class A -> get(A a) */ String get(C c) { return "AA"; } } class B extends A { // TODO String get(A a) { return "BA"; } // TODO String get(B b) { return "BB"; } /* * 说明:类B 没有方法get(C c),且父类A 也没有该方法,而类C 是B 的子类,类B 的方法get(C c)就近继承get(B b) * 关系:class B -> get(B b) */ String get(C c) { return "BB"; } /* * 说明:类B 的父类A 存在方法get(D d),直接继承过来。 * 关系:class A -> get(D d) */ String get(D d) { return "AD"; } } class C extends B { /* * 说明:父类B 中有方法get(A a),直接集成过来即可。 * 关系:class B -> get(A a) */ String get(A a) { return "BA"; } /* * 说明:父类B 中有方法get(B b),直接集成过来即可。 * 关系:class B -> get(B b) */ String get(B b) { return "BB"; } /* * 说明:类C 与类D 都继承于B。父类B 中没有get(C c),B 的父类A 中也没有此方法,则类C 继承类B 的get(B b)。 * 关系:class B -> get(B b) */ String get(C c) { return "BB"; } /* * 说明:父类B 继承于类A,A中有方法get(D d),直接继承过来即可。 * 关系:class A -> get(D d) */ String get(D d) { return "AD"; } } class D extends B { String get(A a) { return "BA"; } String get(B b) { return "BB"; } String get(C c) { return "BB"; } String get(D d) { return "AD"; } }
四、面试题结果
补充子类全部方法后 DDDL.java 运行结果
图4-1.面试题结果图
上面补充的方法和注释是否正确。我们通过一段测试代码测试一下面试题 LVXQ.java 及补充全部方法后的面试题 DDDL.java。测试代码如下
String result = "A : " + a.get(a) + " - " + a.get(b) + " - " + a.get(c) + " - " + a.get(d) + "\nB : " + b.get(a) + " - " + b.get(b) + " - " + b.get(c) + " - " + b.get(d) + "\nC : " + c.get(a) + " - " + c.get(b) + " - " + c.get(c) + " - " + c.get(d) + "\nD : " + d.get(a) + " - " + d.get(b) + " - " + d.get(c) + " - " + d.get(d); System.out.println(result);
测试代码运行结果如下:
图4-2.LJXQ.java测试结果图
图4-3.DDDL.java测试结果图