继承与多态
一.继承
1. 继承的概念:
继承在本职上是特殊——一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的
一些属性或方法。
2. 继承中的初始化顺序:在上一篇博客中已详述,此处不在赘述
3.继承中的隐藏:
隐藏含义:实际上存在,但是对外不可见。
Java类具有三种访问控制符:private、protected和public,同时当不写这三个访问控制符时,表现为一种默认的访问控制状态。因此,一共具有四种访问控制级别。
具体访问控制表现如下:
private修饰的属性或方法为该类所特有,在任何其他类中都不能直接访问;
default修饰的属性或方法具有包访问特性,同一个包中的其他类可以访问;
protected修饰的属性或方法在同一个包中的其他类可以访问,同时对于不在同一个包中的子类中也可以访问;
public修饰的属性或方法外部类中都可以直接访问。
当子类继承父类,子类可以继承父类中具有访问控制权限的属性和方法(一般来说是非private修饰的),对于private修饰的父类所特有的属性和方法,子类是不继承过来的。
当子类需要改变继承过来的方法或者属性时,,父类的方法或属性对子类来说表现为隐藏。但子类对象中想调用父类原来的方法与属性时,可以通过如下两种方式:
1.将子类对象类型强制转化为父类类型,进行调用;
2.通过super调用。
4.继承中的this和super:
构造器中的this表示当前正在初始化的对象引用,方法中的this表示当前正在调用此方法的对象引用。this具体用法表现在一下几个方面:
1.当具多个重载的构造器时,且一个构造器需要调用另外一个构造器,在其第一行使用this(param)形式调用,且只能在第一行;
2.当对象中一个方法需要调用本对象中其他方法时,使用this作为主调,也可以不写,实际上默认就是this作为主调;
3.当对象属性和方法中的局部变量名称相同时,在该方法中需要显式的使用this作为主调,以表示对象的属性,若不存在此问题,可以不显式的写this。
4.super表示调用父类中相应的属性和方法。如果子类构造器想调用父类的构造器,super()必须放第一行
5. 继承中的静态变量和静态方法:
静态变量和静态方法子类可以继承,如果子类中存在和父类一样名称的父类静态变量或者方法,那么分为两种情况:
Parent是Child的父类,且都有名称一样的静态方法print();父类打印你好,子类打印fuck;
情况一:Parent a=new Child(); a.print();//打印你好 类型是parent
情况二:Child a=new Child(); a.print();//打印fuck; 类型是child,发生隐藏
很简单:statit修饰的方法和属性在调用方法或者选择变量时类型与方法或者变量的绑定是静态绑定。下面会继续提到。
二.多态
提到多态不得不提到向上转型,那么在一个向上转型的模型下,会出现哪些多态问题呢?
1.重写与重载:
方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。
调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。
方法重写:父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。
但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
2.程序绑定:绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来
在Java中存在两种绑定方式,一种为静态绑定,又称作早期绑定。另一种就是动态绑定,亦称为后期绑定。
区别:
- 静态绑定发生在编译时期,动态绑定发生在运行时
- 使用private或static或final修饰的变量或者方法,使用静态绑定。而非静态方法则会根据运行时的对象进行动态绑定。
- 静态绑定使用类信息来完成,而动态绑定则需要使用对象信息来完成。
- 重载(Overload)的方法使用静态绑定完成,而(除去静态方法的重写)重写(Override)的方法则使用动态绑定完成。
确定绑定方式:静态类型的面向对象语言消息传递表达是的合法性是基于接收器的静态类决定的。
之后判断是调用的方法选择问题是重载还是重写,重写动态绑定,重载静态绑定。
3.方法选择:挑选一个最为匹配的方法,如果没有没有完全一样的向上转型在寻找
4.针对好多地方出现的“静态方法无重写”这句话:我感觉有些片面,举个例子:
Parent是Child的父类,且都有名称一样的静态方法print();父类打印你好,子类打印fuck;
情况一:Parent a=new Child(); a.print();//打印你好 类型是parent
情况二:Child a=new Child(); a.print();//打印fuck; 类型是child,发生隐藏
情况二确实发生了重写,所以无重写并不特别贴切,更确切的说法是静态方法无多态意义下的重写。
5.用上述知识分析问题:
一个小题目:
(一)相关类
class A ...{ public String show(D obj)...{ return ("A and D"); } public String show(A obj)...{ return ("A and A"); } } class B extends A...{ public String show(B obj)...{ return ("B and B"); } public String show(A obj)...{ return ("B and A"); } } class C extends B...{} class D extends B...{}
(二)问题:以下输出结果是什么?
A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b)); ① System.out.println(a1.show(c)); ② System.out.println(a1.show(d)); ③ System.out.println(a2.show(b)); ④ System.out.println(a2.show(c)); ⑤ System.out.println(a2.show(d)); ⑥ System.out.println(b.show(b)); ⑦ System.out.println(b.show(c)); ⑧ System.out.println(b.show(d)); ⑨
参考:http://www.cnblogs.com/lwbqqyumidi/p/3509992.html