面向对象高级特性二
上转型对象(上溯)
如果A类是B类的父类,当我们用子类创建对象,并把这个对象的引用放到父类的对象中时:
A a;
B b=new B(); 或 A a=new B();
a=b;
称父类对象a是子类对象b的上转型对象。
上转型对象特点
上转型对象的实体是子类负责创建的,所以上转型对象失去原对象一些属性和功能。
v 不能操作子类新增的成员变量和方法;
v 可以操作子类继承的变量,也可操作子类继承或重写的方法;
v 如果子类重写了父类的某个方法后,当对象的上转型对象调用这个方法时一定是调用了这个重写的方法。
v 不要将父类创建的对象和子类对象上转型对象混淆;
v 可以将对象的上转型对象再强制转换到一个子类对象,这时,该子类对象又具备了子类所有属性和功能;(即下溯)
v 不可以将父类创建的对象的引用赋值给子类声明的对象(不能说”哺乳动物是老虎”);
类型提升及强制条件
v 类型自动提升和强制类型转换的条件:
v 创建对象的类之间存在继承关系。
什么是多态
v 当一个类有很多子类时,并且这些子类都重写了父类中的某个方法。那么当我们把子类创建的对象的引用放到一个父类的对象中时(即上转型对象),那么这个上转型对象调用这个方法时就具有多种形态,因为子类在重写父类方法时可能生产不同行为。
v 多态就是指父类的某个方法被子类重写时,可以各自产生自己的功能行为。
v 多态性中父类一般抽象为一个接口,(有多个实现类实现接口中某个方法)
v java在运行时动态方法调用叫做后期绑定(late binding)根据具体引用的实例来决定调用的实例方法或者叫运行期绑定
v 编译期间进行的绑定(静态绑定或者前期绑定)
v 对象的属性以及对象的类方法采取是前期绑定
§ 即与变量的声明类型进行绑定
要点补充:
Final的使用
final在类之前:表示该类是最终类,表示该类不能再被继承。
final在方法之前:表示该方法是最终方法,该方法不能被任何派生的子类覆盖。
final在变量之前:表示变量的值在初始化之后就不能再改变;相当于定义了一个常量。
==========================对象的上溯(上转型)和对象的下溯=======================
上转型对象的特点:
A a = new B();实例化是B,只不过是A去接收而已。所以只能看到A中定义的属性与方法。
A:不能操作子类新增的成员变量和方法;
B:可以操作子类继承的变量,也可操作子类继承或重写的方法;
如果子类重写了父类的某个方法后,当对象的上转型对象调用这个方法时一定是调用了这个子类重写的方法。
使用上转型对象的优缺点:
缺点:不能操作子类新增的成员变量和方法
优点:
A:上转型对象是实现对象多态的前提条件。
B:以牺牲少部分的功能来换取代码设计的最大幅度的优化。
ClassBaseOption{
public booeaninsert();
public booleanupdate();
public booleandelete();
//public ListgetList();
}
class UserOptionextends BaseOption{
public booeaninsert();
public booleanupdate();
public booleandelete();
//public ListgetList();
public booleanisUser(String username);
}
classNoticeOption extends BaseOption{
public booeaninsert();
public booleanupdate();
public booleandelete();
//public ListgetList();
public booleanisApprove(int noticeID);
}
main(){
BaseOption base= new UserOption();
base.insert();
BaseOption base2= new NoticeOption();
base2.update();
}
类型的下溯:
如果此时上转型对象想要操作子类新增的方法和属性,可以进行对象类型的下溯。
下溯成功后,就可以看到自已新增的属性与方法。
类型的上/下溯的注意点:
操作的对象都是针对子类进行上/下的转换。
操作的上/下转型对象之间必须要有继承关系。
=============重载和重写====================
重载
当有参数精确匹配时,调用的是精确匹配的方法。
如果没有,寻找参数对应的父类类型。(Object,String,StringBuffer)
重写/上转型对象:一旦用上转型对象的话,方法被子类重写,肯定调用的是子类重写的方法。
================多态================
1:什么是多态:
多态就是指父类的某个方法被子类重写时,可以各自产生自己的功能行为。
多态指当系统A访问系统B的服务时,系统B可以通过多种实现方式来提供服务。
2:多态的条件
A:要有继承关系
B:子类必须对父类的方法进行重写
C:父类的引用要指向子类(对象的上转型)。
3:多态的中的父类的引用要指向子类造成了多态的后期绑定。
========前期绑定与后期绑定:========
前期绑定:编译期间就已经确定其类型。
后期绑定:在运行期间才确定对象类型。
1.对于一个引用类型的变量,JAVA编译器按照它声明的类型来处理。
Base who = newSub();
who.a;失败。在base类中没有a属性。
Java编译器允许在具有直接或间接继承关系的类直接进行类型转换,
对于向上转型,不必使用强制类型转换,因为子类的对象肯定也可以看做父类的对象。
Dog dog = newDog();
Creaturecreature = dog;
对于向下转型,必须进行强制类型转换。//
Creaturecreature = new Cat();
Cat cat=(Cat)creature;
假如两种类型之间没有继承关系,不在继承树的同一继承分支上,那么JAVA编译器不允许进行类型转换。
Dog dog = newDog();
Cat cat=(Cat)dog;
2.对于一个引用类型的变量,运行时虚拟机按照它实际引用的对象来处理。
Base who = newBase();
Sub s =(Sub)who;
在运行时,子类对象可以转换为父类类型,而父类的对象实际无法转换为子类类型,因为父类拥有的成员子类肯定有,
而子类拥有的成员父类不一定有。
sub引用变量实际上引用的是base类的实例。在运行时,JAVA虚拟机无法把子类对象转换为父类对象。
3.在运行环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定机制。
1.实例方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由java虚拟机动态决定的。
2.成员变量与引用变量所声明的类型的成员变量绑定,这种绑定属于静动态绑定,因为是在编译阶段就已做了绑定。
关于Eclipse 的一些小知识:
Eclipse中编译环境与运行环境的设定。
编译环境:javac
运行环境:java
因为高版本往低版本兼容。所以运行环境>=编译环境。
所有工程的设定:
编译环境:window-->preference-->java-->Compiler:设定编译环境。
运行环境:window-->preference-->java-->Install JRES:设定运行环境。
指定工程的设定:
编译环境:右键选择工程-->properties--->Java Compiler:设定编译环境
运行环境:右键选择工程-->properties--->Java Build Path-->Librarys:设定运行环境