一、面试题
面试题 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";
}
/*
* 说明:a.get(c); 类 A 中没有 get(C c) 方法;但是有 get(A a) 方法;
* 类C 继承于B,类B 的父类是A,类方法get(C c)就近原则继承 get(B a); 没有 get(B b),就近原则 get(A a);即a.get(C c) 的实现逻辑继承 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测试结果图