多态性
1:什么是多态性
多态性是面向对象中的第三大主要特征,多态性是在继承的基础上扩展出来的概念,也就是说可以实现父子类之间的互相转换处理。
2:Java中多态性的两种实现方式
A:方法的多态性:方法的重载;方法的覆写。
A-a:方法的重载:同一个方法名称可以根据传入的参数的类型或个数的不同实现不同功能的执行;
A-b:方法的覆写:同一个方法可能根据使用子类的不同有不同的实现;
//重载Demo如下:
class Message{
public void print(){
System.out.println("就是要进头条");
}
public void print(String str){
System.out.println(str);
}
}
//覆写Demo如下
class Message{
public void print(){
System.out.print("请叫我小超超")
}
}
class DataBaseMessage extends Message{
public void print(){
System.out.println("是一个善良的人");
}
}
calss NetworkMessage extends Message{
public void print(){
System.out.println("网络连接信息");
}
}
B:对象的多态性:父子实例之间的转换处理,他有两种模式:对象向上转型;对象向下转型。
B-a:对象向上转型;(自动完成转换)
父类 父类实例 = 子类实例;
B-b:对象向下转型(强制完成转换)
子类 子类实例 = (子类)父类实例;
从实际的转型处理来讲,大部分情况下考虑最多的一定是对象的向上转型(90%);
对于对象的向下转型往往都在使用子类特殊功能(子类可以对父类进行功能扩充)的时候采用向下转型(3%),还有一些时候是不会考虑转型的(String类,7%)。
3:对象的向上转型(接收或返回参数的统一性)
对象转型的处理属于多态性,而这一特性必须在继承的基础上实现。
//先观察正常的覆写操作
class Message {
public void print() {
System.out.println("www.mldn.cn") ;
}
}
class DataBaseMessage extends Message {
public void print() {
System.out.println("Oracle数据库连接信息....") ;
}
}
public class JavaDemo {
public static void main(String args[]) {
DataBaseMessage msg = new DataBaseMessage() ;
msg.print() ;
}
}
//本程序是一个最简单的方法覆写操作实现,整体的程序之中可以发现,由于现在实例化的是子类对象,并且子类对象覆写了父类中的print()方法,所以调用的是被覆写过的方法。
//观察向上转型
class Message {
public void print() {
System.out.println("www.mldn.cn") ;
}
}
class DataBaseMessage extends Message {
public void print() {
System.out.println("Oracle数据库连接信息....") ;
}
}
public class JavaDemo {
public static void main(String args[]) {
Message msg = new DataBaseMessage() ; // 向上转型
msg.print() ;
}
}
//下面考虑向上转型这种操作有什么作用。
class Message {
public void print() {
System.out.println("www.mldn.cn") ;
}
}
class DataBaseMessage extends Message {
public void print() {
System.out.println("Oracle数据库连接信息....") ;
}
}
class WebServerMessage extends Message {
public void print() {
System.out.println("WEB服务器连接信息....") ;
}
}
public class JavaDemo {
public static void main(String args[]) {
fun(new DataBaseMessage()) ; // Message msg = new DataBaseMessage()
fun(new WebServerMessage()) ; // Message msg = new WebServerMessage()
}
public static void fun(Message msg) { // 不管现在传递是那一个子类都可以接收
msg.print() ;
}
}
向上转型的主要特点在于,可以对参数进行统一的设计;如果用函数重载实现,观察下面代码效果。
class Message {
public void print() {
System.out.println("www.mldn.cn") ;
}
}
class DataBaseMessage extends Message {
public void print() {
System.out.println("Oracle数据库连接信息....") ;
}
}
class WebServerMessage extends Message {
public void print() {
System.out.println("WEB服务器连接信息....") ;
}
}
public class JavaDemo {
public static void main(String args[]) {
fun(new DataBaseMessage()) ; // Message msg = new DataBaseMessage()
fun(new WebServerMessage()) ; // Message msg = new WebServerMessage()
}
public static void fun(DataBaseMessage msg) {
msg.print() ;
}
public static void fun(WebServerMessage msg) {
msg.print() ;
}
}
//现在的代码利用重载解决了当前的设计,的确可以实现和之前一样的功能,但是在进行程序类设计的时候除了满足于当前的要求之外,还需要做出可维护性的设计,如果说现在随着项目的发展,Message产生了3W个子类,那么这个时候每当扩充了一个Message之后就需要追加一个fun()方法重载,这样就对程序的维护造成了很大的影响。
4:对象的向下转型
向下转型的主要特点在于需要使用到一些子类自己特殊的定义处理。
//范例:实现向下转型
class Person {
public void print() {
System.out.println("一个正常的人类行为,吃饭、睡觉、繁衍。") ;
}
}
class SuperMan extends Person {
public String fly() {
return "我可以飞。。。" ;
}
public String fire() {
return "我可以喷火。。。" ;
}
}
public class JavaDemo {
public static void main(String args[]) {
System.out.println("---------- 正常状态下的超人应该是一个普通人的状态 --------------") ;
Person per = new SuperMan() ; // 向上转型
per.print() ;
System.out.println("---------- 外星怪兽狗骚扰地球,准备消灭人类 --------------") ;
SuperMan man = (SuperMan) per ; // 向下转型
System.out.println(man.fly()) ;
System.out.println(man.fire()) ;
}
}
向上描述的是一些公共的特征,而向下转型描述的是子类自己特殊的定义环境;
向下转型之前一定要首先发生向上转型(所以向下转型并不是一件安全的事情,观察下面错误的代码);
class Person {
public void print() {
System.out.println("一个正常的人类行为,吃饭、睡觉、繁衍。") ;
}
}
class SuperMan extends Person {
public String fly() {
return "我可以飞。。。" ;
}
public String fire() {
return "我可以喷火。。。" ;
}
}
public class JavaDemo {
public static void main(String args[]) {
System.out.println("---------- 正常状态下的人应该是一个普通人的状态 --------------") ;
Person per = new Person() ; // 不转型
per.print() ;
System.out.println("---------- 外星怪兽狗骚扰地球,准备消灭人类 --------------") ;
SuperMan man = (SuperMan) per ; // SuperMan类与Person类
}
}
//以后只要是发生对象的向下转型之前一定要首先发生向上转型,两个没有任何关系的实例如果发生强制转换,那么就会出现“ClassCastException”异常,所以向下转型并不是一件安全的事情。
5:instanceof关键字
通过上述所学,向下转型是一件存在有安全隐患的操作,所以为了保证向下转型的正确性,往往需要在进行转型之前进行判断,判断某个实例是否是某个类的对象,这个就需要通过instanceof语法。
对象 instanceof 类 (该判断返回一个boolean类型,如果是true表示实例是指定类的对象)
//不发生转型
class Person {
public void print() {
System.out.println("一个正常的人类行为,吃饭、睡觉、繁衍。") ;
}
}
class SuperMan extends Person {
public String fly() {
return "我可以飞。。。" ;
}
public String fire() {
return "我可以喷火。。。" ;
}
}
public class JavaDemo {
public static void main(String args[]) {
Person per = new Person() ; // 不转型
System.out.println(per instanceof Person) ; // true
System.out.println(per instanceof SuperMan) ; // false
}
}
//发生转型
class Person {
public void print() {
System.out.println("一个正常的人类行为,吃饭、睡觉、繁衍。") ;
}
}
class SuperMan extends Person {
public String fly() {
return "我可以飞。。。" ;
}
public String fire() {
return "我可以喷火。。。" ;
}
}
public class JavaDemo {
public static void main(String args[]) {
Person per = new SuperMan() ; // 向上转型
System.out.println(per instanceof Person) ; // true
System.out.println(per instanceof SuperMan) ; // true
}
}
所以在日后进行项目的开发过程之中,如果要执行对象的向下转型,最好先判断一次。(代码如下)
class Person {
public void print() {
System.out.println("一个正常的人类行为,吃饭、睡觉、繁衍。") ;
}
}
class SuperMan extends Person {
public String fly() {
return "我可以飞。。。" ;
}
public String fire() {
return "我可以喷火。。。" ;
}
}
public class JavaDemo {
public static void main(String args[]) {
Person per = new SuperMan() ; // 向上转型
if (per instanceof SuperMan) {
SuperMan man = (SuperMan) per ;
System.out.println(man.fly()) ;
System.out.println(man.fire()) ;
}
}
}
总结:在以后进行一些完善性的程序的开发过程中,对于转型一定要使用instanceof判断!
沉稳,有一颗强大的内心。做到真正的沉稳,荣辱不惊!YOU CAN DO IT.