一、继承、接口与多态的相关问题:
1、 继承的作用?好处?坏处?
继承:通过继承实现代码复用。Java中所有的类都是通过直接或间接地继程java.lang.Object类得到的。继承而得到的类称为子类,被继承的类称为父类。子类不能继承父类中访问权限为private的成员变量和方法。子类可以重写父类的方法,及命名与父类同名的成员变量。但Java不支持多重继承,即一个类从多个超类派生的能力。
优点:a因为大部分是继承而来的,实现代码重用,减少代码书写量;
b很容易修改和扩展已有的实现
缺点:a打破了封装,因为基类向子类暴露了实现细节
b白盒重用,因为基类的内部细节通常对子类是可见的
c当父类的实现改变时可能要相应的对子类做出改变
d不能在运行时改变由父类继承来的实现
2、 接口的好处?坏处?
优点:帮助Java语言实现一个类似于多继承的功能.但是实现的多继承功能不会使代码中的类之间出现网状关系,而是比较清楚的树状关系,类似于家谱的感觉。
缺点:如果向一个java接口加入一个新的方法时,所有实现这个接口的类都得编写具体的实现。
3、 多态的作用?好处?坏处?
作用:简单的说就是一个接口,多种实现;继承的表现就是多态(没有继承就没有多态。)
a应用程序不必为每一个派生类编写功能调用,只需要对抽象基类进行处理即可。大大提高程序的可复用性。
b派生类的功能可以被基类的方法或引用变量所调用,这叫向后兼容,可以提高可扩充性和可维护性。
优点:a可替换性(可以替换一存在的代码);
b可扩充性(增加新的子类不影响原有类的特性);
c接口性;
d灵活性;
e简化性
缺点:a“遮盖”私有方法。只有非private的方法才能够被笼罩,尽管编译器不会报错,然而也不会遵照我们所渴望的来实行。在导出类中,对于基类中的private方法,优秀采纳不同的名字。
b域在转型时候的问题。对于成员变量(域),导出类将占有从基类承袭而来的成员变量和自己的成员变量(变量名字相一同也是如此),况且,将分摊不同的存储空间,这么,导出类将具有两个名目一样的域。为了取得基类的域,务须实际地著名super.field能力走访,而默许的域则是导出类自己的域。
c静态计策是与类相关系的,而非与某个对象相干联的,那么它就不拥有多态行动。
4、 什么是重载?什么是重写?
重载:
a方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载Overloading是一个类中多态性的一种表现。
b Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。
c重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。
重写:
a父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
b若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
c子类函数的访问修饰权限不能少于父类的;
java的继承与覆盖基本是java笔试中常出的题,也比较绕,我这里对java的继承覆盖做一个总结
1.构造函数:
当子类继承一个父类时,构造子类时需要调用父类的构造函数,存在三种情况
(1),父类无构造函数或者一个无参数构造函数,子类若无构造函数或者有无参数构造函数,子类构造函数中不需要显式调用父类的构造函数,系统会自动在调用子类构造函数前调用父类的构造函数
(2),父类只有有参数构造函数,子类在构造方法中必须要显示调用父类的构造函数,否则编译出错
(3),父类既有无参数构造函数,也有有参构造函数,子类可以不在构造方法中调用父类的构造函数,这时使用的是父类的无参数构造函数
//以上三个结论已经过代码验证
2.方法覆盖:
(1)子类覆盖父类的方法,必须有同样的参数返回类型,否则编译不能通过
(2)子类覆盖父类的方法,在jdk1.5后,参数返回类可以是父类方法返回类的子类
(3)子类覆盖父类方法,可以修改方法作用域修饰符,但只能把方法的作用域放大,而不能把public修改为private
(4)子类方法能够访问父类的protected作用域成员,不能够访问默认的作用域成员
(5)子类的静态方法不能隐藏同名的父类实例方法
(6)java与C++一样,继承的方法具有多态性
//以上6个结论已经过代码验证
3.成员覆盖:
(1)当子类覆盖父类的成员变量时,父类方法使用的是父类的成员变量,子类方法使用的是子类的成员变量
这个听起来很容易理解的一回事,但是实际使用过程中很多人容易搞混:尤其是在多态的时候,调用一个被继承的方法,该方法访问是一个被覆盖的成员m,那么方法中到底是访问了父类的成员还是子类的成员m?结论是,若实际调用的是父类的方法,就使用了父类的该成员m,若实际调用的是子类的方法,就使用子类的成员m,记住一句,每个类使用成员都相当于在前面加了 一个this指针。
//以上1个结论已经过代码验证
我在论坛上看到下面例子,理解上面,你就能够很好得出答案了:
[c-sharp]
view plain
copy
1. class SuperClass {
2. private int number;
3.
4.
5. public SuperClass() {
6. this.number = 0;
7. }
8.
9.
10. public SuperClass(int number) {
11. this.number = number;
12. }
13.
14.
15. public int getNumber() {
16. number++;
17. return number;
18. }
19. }
20.
21. class SubClass1 extends SuperClass {
22. public SubClass1(int number) {
23. super(number);
24. }
25.
26. }
27.
28. class SubClass2 extends SuperClass {
29. private int number;
30.
31.
32. public SubClass2(int number) {
33. super(number);
34. }
35.
36. }
37.
38. public class SubClass extends SuperClass {
39.
40. private int number;
41.
42.
43. public SubClass(int number) {
44. super(number);
45. }
46.
47.
48. public int getNumber() {
49. number++;
50. return number;
51. }
52.
53.
54. public static void main(String[] args) {
55. new SubClass(20);
56. new SubClass1(20);
57. new SubClass2(20);
58. out.println(s.getNumber());
59. out.println(s1.getNumber());
60. out.println(s2.getNumber());
61. //结论一:多态时,当子类覆盖了父类的方法,使用子类覆盖的方法
62. //结论二:当子类覆盖父类的成员变量时,父类方法使用的是父类的成员变量,子类方法使用的是子类的成员变量
63. }
64.
65. }
执行输出:
1
21
21